+
{{
confirmation.data.event.free_event ? __("Registration Confirmed") : __("Booking Confirmed")
}}
+
+
{{ __("Payment Pending") }}
+
+ {{
+ __(
+ "We have not received your payment yet. If you have paid, it can take a minute to reach us.",
+ )
+ }}
+
+
+
@@ -85,6 +98,12 @@ const { showSuccessMessage, showSuccess } = usePaymentSuccess({
cleanupUrl: false,
})
+// The shopper's return proves nothing; only a paid (or free) booking is confirmed.
+function isBookingConfirmed(data: Record
| null | undefined) {
+ return Boolean(data?.event?.free_event || data?.booking?.payment_status === "Paid")
+}
+const isConfirmed = computed(() => isBookingConfirmed(confirmation.data))
+
const showPaymentSummary = computed(() => {
const booking = confirmation.data?.booking
return booking && (booking.total_amount || 0) > 0
@@ -94,6 +113,8 @@ const confirmation = useCall, Record>({
url: "/api/v2/method/buzz.api.booking.get_booking_confirmation",
params: { booking_id: props.bookingId, token: route.query.token },
onSuccess: (data) => {
+ // useCall runs onSuccess before it sets confirmation.data, so read the response itself.
+ if (!isBookingConfirmed(data)) return
showSuccess()
// Clear any stored booking form data now that the booking is confirmed
if (data?.event?.route) {
diff --git a/dashboard/src/pages/SponsorshipDetails.vue b/dashboard/src/pages/SponsorshipDetails.vue
index 7744af44e..8b9cb945e 100644
--- a/dashboard/src/pages/SponsorshipDetails.vue
+++ b/dashboard/src/pages/SponsorshipDetails.vue
@@ -316,7 +316,7 @@
import { Badge, Button, Dialog, ErrorMessage, FileUploader, Spinner, useCall } from "frappe-ui"
import { toast } from "frappe-ui"
import { dayjsLocal } from "frappe-ui"
-import { computed, ref } from "vue"
+import { computed, ref, watch } from "vue"
import LucideCheckCircle from "~icons/lucide/check-circle"
import LucideClock from "~icons/lucide/clock"
import LucideXCircle from "~icons/lucide/x-circle"
@@ -376,13 +376,12 @@ const updateLogoResource = useCall({
onError: (error) => console.error("Failed to update company logo:", error),
})
-// Use the payment success composable
-const { showSuccessMessage } = usePaymentSuccess({
- onSuccess: () => {
- // Reload the enquiry details to get updated status
- enquiryDetails.reload()
- },
-})
+// Back from the payment page: celebrate only once the enquiry is actually paid.
+const { showSuccessMessage, checkForSuccess } = usePaymentSuccess({ checkOnMount: false })
+watch(
+ () => enquiryDetails.data?.enquiry?.status,
+ (status) => status === "Paid" && checkForSuccess(),
+)
// Check if inquiry can be withdrawn (not paid and not already withdrawn)
const canWithdraw = computed(() => {
diff --git a/dashboard/src/types.ts b/dashboard/src/types.ts
index 4015ae4d7..429b8d6d3 100644
--- a/dashboard/src/types.ts
+++ b/dashboard/src/types.ts
@@ -549,6 +549,12 @@ export interface CurrencyItem {
number_format: string | null
}
+export interface PaymentGatewayLogo {
+ name: string
+ logo: string
+ logo_dark: string
+}
+
export interface TierPrice {
currency: string
price: number
diff --git a/dashboard/src/utils/paymentGateways.test.ts b/dashboard/src/utils/paymentGateways.test.ts
deleted file mode 100644
index e2fc78f4e..000000000
--- a/dashboard/src/utils/paymentGateways.test.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import assert from "node:assert/strict"
-import { test } from "node:test"
-
-import { paymentGatewayLogo } from "./paymentGateways.ts"
-
-test("matches a gateway by its exact name", () => {
- assert.equal(
- paymentGatewayLogo("Razorpay")?.light,
- "/assets/buzz/images/payment_gateways/razorpay.svg",
- )
-})
-
-test("matches an account-suffixed gateway by its provider", () => {
- assert.equal(
- paymentGatewayLogo("Razorpay-Main")?.dark,
- "/assets/buzz/images/payment_gateways/razorpay-dark.svg",
- )
-})
-
-test("returns nothing for an unknown gateway or offline method", () => {
- assert.equal(paymentGatewayLogo("Bank Transfer"), undefined)
-})
diff --git a/dashboard/src/utils/paymentGateways.ts b/dashboard/src/utils/paymentGateways.ts
deleted file mode 100644
index d808778bf..000000000
--- a/dashboard/src/utils/paymentGateways.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-const LOGO_DIRECTORY = "/assets/buzz/images/payment_gateways"
-
-// Brand marks are drawn for one background, so each gateway ships a version per theme.
-interface PaymentGatewayLogoFiles {
- light: string
- dark: string
-}
-
-const LOGOS: Record = {
- Razorpay: {
- light: `${LOGO_DIRECTORY}/razorpay.svg`,
- dark: `${LOGO_DIRECTORY}/razorpay-dark.svg`,
- },
-}
-
-// Gateways with per-account settings are named "-", e.g. "Stripe-Main".
-export const paymentGatewayLogo = (gateway: string): PaymentGatewayLogoFiles | undefined =>
- LOGOS[gateway.split("-")[0]]
diff --git a/dashboard/vite.config.ts b/dashboard/vite.config.ts
index 47e549110..93779d2f8 100644
--- a/dashboard/vite.config.ts
+++ b/dashboard/vite.config.ts
@@ -9,7 +9,7 @@ export default defineConfig({
frappeui({
frappeProxy: {
port: 8080,
- source: "^/(app|login|api|assets|files|private|razorpay_checkout|events|community)",
+ source: "^/(app|login|api|assets|files|private|events|community)",
},
jinjaBootData: true,
lucideIcons: true,
diff --git a/pyproject.toml b/pyproject.toml
index 3c528f838..a85325211 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -61,4 +61,4 @@ indent-style = "tab"
[tool.bench.frappe-dependencies]
frappe = ">=16.0.0,<18.0.0"
-payments = ">=0.0.1,<1.0.0"
\ No newline at end of file
+bwh_payments = ">=0.0.1,<1.0.0"
\ No newline at end of file