Bank transfer payments
OpenShopy does not use any external payment provider. Customers pay by ordinary bank transfer to your account and your team confirms each payment.
How it works
- Order is placed through checkout or the API. It starts as
payment_status: "unpaid"and gets a payment deadline (payment_due_at) based on Settings → Payment deadline. - The customer sees the payment page at
https://your-openshopy-domain/order/<payment_token>. The order returned by checkout and byGET /orders/:idcontains it aspayment.page_url. The page shows:- amount and currency
- account holder, bank name, IBAN and SWIFT
- the transfer title (payment reference), e.g.
Order #1001 - a Polish banking-app QR code (for PLN) and an EPC/SEPA QR code (for EUR)
- copy buttons for every field, order summary, shipping status and tracking links
- The customer clicks “I have paid”. The order moves to
awaiting_confirmation, an alert appears for the team (bell icon in the header) and thepayment.customer_markedautomation event fires. Your own storefront can do the same withPOST /payments/:token/mark-sent. - Staff verifies the transfer in the bank account and clicks Confirm payment on the order (or calls
POST /orders/:id/confirm-payment). The order becomespaid,paid_atand the confirming person are recorded in the audit log. - After confirmation the
payment.confirmedevent fires. Default behaviour:- the order status changes from
opentoprocessing - a payment received notification is queued for the customer
- an invoice is issued automatically if Settings → Auto-issue invoice is on
- the order status changes from
Staff can also confirm a payment directly from unpaid (for example when the money arrives before the customer clicks the button), and can revert a mistaken confirmation with Mark as unpaid.
Embedding the payment page
The payment page is fully hosted and public (no login needed — the token is unguessable). You can:
- redirect to it after checkout
- link to it in your own emails (
{order_url}placeholder in notification templates) - read the same data from your own server with
GET /orders/:idand render a custom page
Transfer title
The transfer title is generated from Settings → Transfer title template. Placeholder: {order_number}. Keep it short — most banks limit titles to 140 characters.
Overdue payments
Orders that are still unpaid after payment_due_at appear in the Overdue tab of the orders list. You can send a reminder (resend the order created message with the bank details) or cancel them; cancelling restores stock.
Refunds
Refunds are recorded, not executed: send the money back from your bank, then record the refund on the order (POST /orders/:id/refunds or the order page). The payment status becomes partially_refunded or refunded, the refund.issued event fires, the customer gets a refund issued message and you can issue a credit note.
Security notes
- The payment token is 64 random hexadecimal characters; treat payment URLs like a password-reset link.
- The page only exposes data needed to pay: order totals, items, shipping status and your public bank details.
- Customers can mark an order as paid only once and only while it is unpaid; it never marks the order
paidon its own.