Early access. Manual payment approval is in early access and rolling out with selected partners. Contact your Primer account team to enable it. Available on the Web SDK today; iOS and Android are coming.
paymentHandling: 'MANUAL' with onTokenizeSuccess / onResumeSuccess callbacks), this guide covers the changes needed to move to the equivalent flow on Primer Checkout: manual payment approval.
This is a focused companion to the main Migration Guide. Start there for the SDK-wide changes (package, initialization, events, styling); this page covers only what’s specific to the manual flow.
What changes
The core shift: in the legacy flow your backend owned the payment lifecycle: it created the payment, inspectedrequiredAction, and routed each step (3DS, resume) back to the SDK. In the new flow your backend makes a single approve-or-abort decision, and Primer owns everything after that.
| Concern | Legacy manual flow | New manual approval flow |
|---|---|---|
| Enabling the flow | paymentHandling: 'MANUAL' (SDK setting) | approvalMode: 'MANUAL' (client session field) |
| Trigger | onTokenizeSuccess(token, handler) callback | primer:payment-approval-required event |
| Your backend call | POST /payments (then POST /payments/{id}/resume) | POST /payment-attempts/{id}/approve (or /abort) |
| Creating the payment | You create it with the paymentMethodToken | Primer creates it when you approve |
| 3DS / required actions | You route requiredAction.clientToken back via handler.continueWithNewClientToken() | Primer handles 3DS and resume automatically |
| Resuming | onResumeSuccess(resumeToken, handler) + POST /payments/{id}/resume | Removed (no resume step) |
| Resolving the UI | handler.handleSuccess() / handler.handleFailure() | continueFlow() (the SDK resolves the UI itself) |
| Outcome | Returned from your POST /payments call | primer:payment-success / primer:payment-failure events |
Step 1. Enable the flow on the client session, not the SDK
Move the manual switch from an SDK setting to a client session field. Legacy (set on the SDK):paymentHandling option.
Step 2. Replace the tokenize/resume callbacks with the approval event
The two callbacks collapse into a single event. Legacy (create the payment and route required actions yourself):POST /payments, no requiredAction inspection, no continueWithNewClientToken, and no onResumeSuccess / resume call. Primer creates and orchestrates the payment after you approve.
Step 3. Swap payment creation for approve / abort
Your backend endpoint changes from creating (and resuming) a payment to approving or aborting the attempt. Legacy:/abort as an explicit, payment-free cancellation.
Step 4. Read the outcome from events
The payment result is no longer the return value of yourPOST /payments call. Listen for the standard payment events instead, the same ones every Primer Checkout integration uses:
Behavior differences to be aware of
- 3DS is automatic. You no longer route
requiredAction.clientTokenback to the SDK. After you approve, Primer stages and resolves 3DS itself. - Retries create a new attempt. On a decline the checkout unlocks the payment form and the customer can retry in the same session; re-tokenizing creates a new
paymentAttemptId. You don’t create a new client session. - There’s a 90-second approval window. If your backend calls neither
/approvenor/abortwithin 90 seconds, the attempt expires. The legacy flow had no such window. paymentAttemptIdis the idempotency key. Duplicate or concurrent approves for the same attempt converge on one payment.
Migration checklist
- Moved the switch: replaced
paymentHandling: 'MANUAL'(SDK) withapprovalMode: 'MANUAL'(client session) - Replaced callbacks: swapped
onTokenizeSuccess/onResumeSuccessfor theprimer:payment-approval-requiredevent +continueFlow() - Replaced backend calls: swapped
POST /payments(and/resume) forPOST /payment-attempts/{id}/approve(or/abort) - Removed required-action routing: deleted
continueWithNewClientTokenand resume handling (Primer handles 3DS) - Read outcomes from events: using
primer:payment-success/primer:payment-failure - Handled abort and the 90s timeout: see the manual payment approval guide
Next steps
Manual payment approval
The full guide for the new flow
Migration Guide
SDK-wide changes for moving to Primer Checkout
Events Reference
primer:payment-approval-required and all events
Client session
Create a session with approvalMode