Move from frappe/payments
An app that takes payments through frappe/payments can move to BWH Payments and keep its gateways and its payment history. Old payments stay readable, and old Razorpay payments stay refundable.
Before you start
- BWH Payments installed on the site, with
frappe/paymentsstill installed. The move reads the frappe/payments records. - A patch in your app, in the
post_model_syncsection ofpatches.txt
1. Import the gateways
from bwh_payments.migrate.frappe_payments import import_gateways
import_gateways()
Each frappe/payments Payment Gateway becomes a Payment Gateway Profile with the same name, for example Razorpay or Stripe-Main. Links in your app that point at a gateway name stay valid. Change the Link fields' options from Payment Gateway to Payment Gateway Profile.
| frappe/payments gateway | Profile |
|---|---|
| Razorpay | Enabled. The key id, key secret and webhook secret are copied to Razorpay Gateway Settings. |
| The first Stripe account | Enabled. The keys are copied to Stripe Gateway Settings. The mode follows the secret key. |
| Another Stripe account | Disabled, without settings. BWH Payments holds one Stripe account. |
| Any other gateway, for example PayPal or Paymob | Disabled, without settings |
A disabled profile without settings keeps the gateway's name for old payments. New payments cannot use it.
import_gateways never overwrites settings that are already filled in, and skips profiles that exist. You can run it again.
2. Record the payment history
Give each old payment a Gateway Payment Request, and each old refund a Gateway Refund:
from bwh_payments.api import record_external_payment, record_external_refund
payment_request = record_external_payment(
"Sales Order",
order.name,
order.grand_total,
order.currency,
"Razorpay", # the gateway name, now a profile
"Paid", # or Expired for a payment that never completed
order_ref=payment_id, # the gateway's order or payment id
transaction_ref=payment_id, # Razorpay: the pay_… id
)
record_external_refund(payment_request.name, refund_id, "Processed", 400, reference=my_refund.name)
- No checkout opens, and your document's
on_payment_authorizedandon_refund_updateare not called. - A
Processedrefund updates the payment's refund total and status. - Both are idempotent, on
order_refand onrefund_id. - For Razorpay, an
order_refthat starts withpay_is refunded against that payment id.
Run each row in a savepoint, and log a row that fails, for example a payment for a deleted order. One bad row must not stop the site's migration.
3. Set up the webhooks
frappe/payments used its own webhook URLs. Register the BWH Payments URL for each gateway:
https://your.site/api/v2/method/bwh_payments.bwh_payments.webhook.handle?gateway=<profile name>
- Add the webhook in the gateway's dashboard, with the events on the gateway's page (Stripe, Razorpay).
- Paste its secret into the gateway's settings. frappe/payments stored no Stripe webhook secret, so Stripe always needs this step.
4. Uninstall frappe/payments
Uninstall it in a later update, after the patch has run on every site:
bench --site your.site uninstall-app payments
Next steps
- Accept a payment: take new payments
- Public API: every function in
bwh_payments.api