Custom integration
Already have your own payment integration — your own card vault, your own arrangement with a provider, anything? Connect it directly. SubCharge never talks to a payment network on your behalf here: it only calls two HTTPS endpoints you host, both signed with a shared secret you choose.
What you implement
| Endpoint | Purpose |
|---|---|
| checkoutUrl | We redirect the customer here to capture (and optionally charge) a payment method — your own page, your own flow |
| chargeUrl | We POST here to request an off-session charge on a previously captured method |
Every request we send is signed: X-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "t.canonical")> — the same scheme as our outbound webhooks.
1. Checkout redirect
We send the customer's browser to checkoutUrl with a reference, the amount, where to send them back, and a notify_url — all signed. Capture the payment method however you like; it never runs on our page. When you're done, redirect back and separately POST the outcome (step 3) — we never infer success from the browser redirect alone.
2. Off-session charge
POST chargeUrl
X-Signature: t=...,v1=...
Idempotency-Key: chg_...
{ "tokenRef": "...", "amountCents": 12345, "reference": "chg_...", "description": "...", "idempotencyKey": "chg_..." }Answer synchronously if you can, or just acknowledge with a bare 2xx and settle later via step 3 — we treat that as pending and wait. A 5xx or a dropped connection is treated as unknown, never as failed: we won't charge again until we've heard back one way or the other.
3. Notify us
POST notify_url
X-Signature: t=...,v1=...
{ "status": "succeeded", "reference": "chg_...", "providerPaymentId": "...", "amountCents": 12345 }status is succeeded, failed (add a declineCategory of soft or hard if you can — hard stops automatic retries) or pending. reference must exactly match what we gave you — an unrecognised reference is a silent 200, not an error, so check your own logs if a notification seems to go missing.