Vault a Payment Source for Future Billing
Tokenise and store a customer's card or bank account now, charge them later.
Persona: CRM integrator, subscription platform, any merchant who onboards customers at sign-up but bills them later.
Scenario: A customer enters their payment details during onboarding. You don't charge them now; you store the payment method against their profile so you can bill them when an invoice is due, a subscription renews, or a trigger fires in your system.
CaptureJS tokens are short-lived. You must callPOST /sourcesto convert the token into a durable source before the token expires. Design your flow soPOST /sourcesis called immediately after tokenisation, not deferred to a background job.
Endpoint sequence
- Client-side:
capture.createToken(...)(CaptureJS) to tokenise the card or bank account POST /payers: create the customer in PinchPOST /sources: immediately save the token as a durable payment source; get back asourceId- Store
payerId+sourceIdin your database - Later, when billing is needed:
POST /paymentsto charge using the storedsourceId
Step 1: Tokenise the payment details (client-side)
Use CaptureJS in the customer's browser. Card and bank account details never touch your server.
<script src="https://cdn.getpinch.com.au/capturejs/pinch.capture.v2.js"
integrity="sha384-hglYFSKC4AMA/rAQOGB3OiA8u5ri5F4qNMGgw4I+fggDSlTmPyREcj1J+VGnkAX8"
crossorigin="anonymous"></script>For a credit card:
var capture = Pinch.Capture({
publishableKey: "pk_test_IPA27NRmeTfCawt00h1Zbt9vitpZEPMH"
});
capture.createToken({
sourceType: "credit-card",
cardNumber: document.getElementById("cardNumber").value,
expiryMonth: document.getElementById("expiryMonth").value,
expiryYear: document.getElementById("expiryYear").value,
cvc: document.getElementById("cvc").value,
cardHolderName: document.getElementById("cardHolderName").value
}).then(function(result) {
// Send result.token to your server immediately
submitTokenToServer(result.token);
});For a bank account:
capture.createToken({
sourceType: "bank-account",
bankAccountName: document.getElementById("bankAccountName").value,
bankAccountRouting: document.getElementById("bankAccountRouting").value, // BSB
bankAccountNumber: document.getElementById("bankAccountNumber").value
}).then(function(result) {
submitTokenToServer(result.token);
});Step 2: Create the payer
On your server, call POST /payers to create the customer record. Store the returned id (pyr_XXXXXXXX).
POST https://api.getpinch.com.au/test/payers
Authorization: ******
pinch-version: 2020.1
Content-Type: application/json
{
"firstName": "Jane",
"lastName": "Smith",
"email": "[email protected]",
"mobile": "0400000000",
"metadata": "{\"customerId\": \"cust_internal_456\"}"
}If the payer already exists in your system (e.g. a returning customer), retrieve their payerId from your database and skip this step.
Step 3: Save the token as a durable source
Do this immediately after receiving the token from CaptureJS. Call POST /sources with the token and the payerId.
POST https://api.getpinch.com.au/test/sources
Authorization: ******
pinch-version: 2020.1
Content-Type: application/json
{
"payerId": "pyr_XXXXXXXX",
"token": "{captureJsToken}"
}Example response:
{
"id": "src_XXXXXXXX",
"payerId": "pyr_XXXXXXXX",
"sourceType": "credit-card",
"last4": "4242",
"expiryMonth": 12,
"expiryYear": 2028
}Store the id (src_XXXXXXXX) in your database. The original CaptureJS token is now consumed; it cannot be used again.
When saving a bank account source, Pinch automatically creates and authorises the Direct Debit Request (DDR) Agreement as part of this call. The payer receives an email with a PDF copy of their DDR. No separate agreement step is needed.
Step 4: Charge the stored source later
When billing is triggered (invoice due, subscription renewal, or any other event in your system), create a payment using the stored payerId and sourceId:
POST https://api.getpinch.com.au/test/payments
Authorization: ******
pinch-version: 2020.1
Content-Type: application/json
{
"payerId": "pyr_XXXXXXXX",
"sourceId": "src_XXXXXXXX",
"amount": 9900,
"description": "Invoice INV-789",
"transactionDate": "2026-08-01",
"metadata": "{\"invoiceId\": \"INV-789\"}"
}See Create or Update Payment for all available fields.
Key caveats
- Token expiry: CaptureJS tokens are short-lived. If your
POST /sourcescall fails with a token expiry error, the customer must re-enter their payment details. Build your UI so tokenisation and source creation happen in the same user session without delay. - Source-to-payer binding: A source is tied to a specific payer. You cannot reuse a
sourceIdacross different payers. - Bank account DDR: The DDR Agreement is created automatically when you save a bank account source. You do not need to take any additional steps to comply with direct debit authorisation requirements for this flow.
- Credit cards: Storing a credit card source does not create any agreement; the card is simply vaulted for future charges.
What to do next
- CaptureJS Tokenisation: full tokenisation reference including available fields
- Create or Update Payment: schedule a payment against a stored source
- Handle a Dishonoured Direct Debit and Retry: what to do when a stored bank account payment fails
Got feedback on this feature?
Send an email to [email protected] or book in a chat with our API team.
Updated about 7 hours ago
