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 call POST /sources to convert the token into a durable source before the token expires. Design your flow so POST /sources is called immediately after tokenisation, not deferred to a background job.


Endpoint sequence

  1. Client-side: capture.createToken(...) (CaptureJS) to tokenise the card or bank account
  2. POST /payers: create the customer in Pinch
  3. POST /sources: immediately save the token as a durable payment source; get back a sourceId
  4. Store payerId + sourceId in your database
  5. Later, when billing is needed: POST /payments to charge using the stored sourceId

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 /sources call 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 sourceId across 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

📘

Got feedback on this feature?

Send an email to [email protected] or book in a chat with our API team.


Did this page help you?