Processing payments
The direct payment flow has three phases: tokenize card data in the browser (so it never touches your servers), validate the payment to get the exact convenience fee, then capture it.
If you want a complete UI instead of raw API calls, use hosted sessions — same engine, none of the plumbing below.
1. Tokenize in the browser
Section titled “1. Tokenize in the browser”Fetch short-lived processor credentials (anonymous endpoint, rate-limited, scoped by the account header):
GET /api/paymentaccounts/{uid}/client-config{ "processor": "zift", "config": { "account_id": "…", "api_key": "…", "temporary_password": "…", "expiration_date": "2026-06-11T18:30:00Z" }, "supported_methods": ["credit", "ach", "apple_pay"]}Feed this to @caselle/payment-sdk’s ZiftPaymentSDK to proxynize the
card: the SDK swaps the real PAN for a token (the fingerprint) valid ~15
minutes. Your server only ever sees the fingerprint.
2. Validate (fee quote)
Section titled “2. Validate (fee quote)”Create the payment without capturing — this validates the method and returns the authoritative convenience fee:
POST /api/paymentsX-Payment-Account-Uid: {uid}{ "base_amount": 12345, "tax_amount": 0, "currency": "USD", "reference_id": "fee-check-7f3a…", "payment_method": { "payment_method_type": "credit", "credit": { "fingerprint": "{proxynized_token}", "last4": "4242", "exp_month": 12, "exp_year": 2027, "bin": "411111", "holder_name": "Alex Morales" } }}ACH uses "payment_method_type": "ach" with an ach object (routing number,
account suffix, account type); saved methods use "wallet_credit" /
"wallet_ach" with "wallet": { "saved_payment_method_uid": "…" }.
{ "uid": "pay_…", "processing_fee_amount": 99, "total_amount": 12444, "payment_method": { "…": "sanitized echo" }}Show processing_fee_amount / total_amount to the customer. Never compute
fees yourself — the engine that charges them quotes them.
3. Capture
Section titled “3. Capture”Once the customer confirms, capture using the validation’s uid, repeating the
exact validated payment method and fee amounts:
POST /api/payments/{uid}/capture{ "base_amount": 12345, "tax_amount": 0, "currency": "USD", "reference_id": "{yourPaymentReference}", "payment_method": { "…": "same as validation" }, "processing_fee_amount": 99, "total_amount": 12444}The response uid is your transaction reference. Then confirm asynchronously
via the payment.completed / payment.failed webhooks —
captures settle through the processor.
Refunds & records
Section titled “Refunds & records”POST /api/payments/{uid}/refund— full or partial refund.POST /api/payments/record-external— record a payment taken outside the platform so reporting stays complete.GET /api/payments,GET /api/transactions— OData-queryable history.