Skip to content

PayUI Tokenisation

PayUI supports secure payment instrument tokenisation, enabling you to store customer payment instruments for future transactions while maintaining PCI compliance. This guide explains how to create and manage tokenised payment instruments during the payment flow, with customer consent.

Overview

Tokenisation allows you to capture customer’s payment details. PayUI captures the customer’s payment instrument information, creates a customer record and payment instrument on your behalf, and returns resource identifiers you can use for subsequent transactions.

Tokenisation occurs transparently within the PayUI iframe — your application never handles raw card data, reducing PCI scope while still giving you the ability to process future recurring or customer-initiated transactions.

How It Works

When you include customerRequest in your Payment Request with paymentInstrument: create, PayUI will:

  1. Collect payment instruments details from the customer in the secure iframe
  2. Capture the payment instrument and process the transaction
  3. Return the transaction and customer and payment instrument identifiers in customerResult in the transaction response

The customer and payment instrument are created only when paymentInstrument: create is explicitly provided.

Integration Steps

Step 1: Create Payment Request with CustomerRequest

Include customerRequest in your Payment Request creation call when you want to tokenise the customer’s card.

Endpoint: POST /paymentrequests

Request with New Customer (tokenisation):

{
"reference": "ORDER-2026-001",
"payment": {
"amount": 5000,
"currencyCode": "AUD",
"description": "Subscription - Premium Plan"
},
"paymentMethods": ["card", "google_pay", "apple_pay"],
"transactionRequest": {
"category": {
"frequency": "single",
"captureType": "auto"
}
},
"customerRequest": {
"paymentInstrument": "create",
"name": "Jane Doe",
"email": "jane.doe@example.com"
}
}

Request without paymentInstrument action (no tokenisation):

If the paymentInstrument is omitted, no payment instrument is created:

{
"reference": "ORDER-2026-002",
"payment": {
"amount": 2500,
"currencyCode": "AUD",
"description": "One-time purchase"
},
"paymentMethods": ["card"],
"transactionRequest": {
"category": {
"frequency": "single",
"captureType": "auto"
}
},
"customerRequest": {
"name": "Jane Doe",
"email": "jane.doe@example.com"
}
}

Response (excerpt):

{
"id": "zWIEEs6BBU2A3GUQ8gD3Ag",
"reference": "ORDER-2026-001",
"createdDateTime": "2026-02-09T10:15:00Z",
"paymentRequestStatus": "created"
}

Step 2: Generate One-Time Token

Generate a one-time token as normal for PayUI integration:

Endpoint: POST /tokens

{
"scope": "payui",
"paymentRequestId": "zWIEEs6BBU2A3GUQ8gD3Ag"
}

Step 3: Initialise PayUI

Initialise PayUI with the one-time token. The tokenisation happens automatically when the customer completes payment:

const config = {
token: "your-one-time-token",
containerId: "payment-container",
version: "1.0.0"
};
const payUI = GPAUNZ.PayUI.initialise(config);
payUI.on('process', (payload) => {
if (payload.result.status === 'approved') {
console.log('Payment approved. Transaction ID:', payload.transactionId);
}
});

Step 4: Retrieve Tokenisation Result

After a transaction, retrieve the customerResult containing the customer and payment instrument identifiers.

If subsrcribed to the payment_requests webhooks, listen for payment request webhooks to capture the final state with customerResult:

{
"id": "zWIEEs6BBU2A3GUQ8gD3Ag",
"eventType": "payment_requests",
"created" : "2026-01-27T06:26:02Z",
"version": "1.0.0",
"payload" : {
"id": "szh-Ib8xP0S_sJZn8xD8yQ",
"reference": "ORDER-723-669-1900",
"createdDateTime": "2026-01-27T06:25:59Z",
"updatedDateTime": "2026-01-27T06:26:43Z",
"expiryDateTime": "2026-01-29T06:25:59Z",
"paymentRequestStatus": "completed",
"transactionResult": {
"id": "Iank9maLpkuwlQWGJ4rYcw",
"location": "https://api.gpaunz.com/transactions/Iank9maLpkuwlQWGJ4rYcw"
},
"customerResult": {
"id": "Iank9maLpkuwlQWGJ4rYcw",
"location": "https://api.gpaunz.com/customers/Iank9maLpkuwlQWGJ4rYcw",
"paymentInstrumentId": "JMFEgR2z5EGL7GF7lAcFxA",
"paymentInstrumentLocation": "https://api.gpaunz.com/customers/Iank9maLpkuwlQWGJ4rYcw/paymentinstruments/JMFEgR2z5EGL7GF7lAcFxA"
},
"payment": {
"description": "i'm a description",
"amount": 100,
"currencyCode": "AUD"
},
"paymentMethods": [
"card"
],
"result": {
"mode": "sandbox",
"status": "ok"
}
}
}

Store the customerResult.id and customerResult.paymentInstrumentId in your database to use for future transactions.

Tokenisation Flow (Sequence Diagram)

This diagram illustrates the complete tokenisation flow from Payment Request creation through to customer and payment instrument creation:

sequenceDiagram
    autonumber
    participant FrontEnd
    participant Merchant Server
    participant Single API
    participant PayUI

    FrontEnd->>Merchant Server: Request payment page
    Merchant Server->>Single API: POST /paymentrequests
    Single API-->>Merchant Server: Payment Request ID
    Merchant Server->>Single API: POST /tokens (scope=payui and paymentrequestid)
    Single API-->>Merchant Server: One-Time Token (OTT)
    Merchant Server-->>FrontEnd: Render page with token
    FrontEnd->>PayUI: Load payui.js
    FrontEnd->>PayUI: GPAUNZ.PayUI.initialise(OTT)
    PayUI-->>FrontEnd: Render iframe + emit 'initialise'
    FrontEnd->>FrontEnd: User enters card details
    PayUI-->>FrontEnd: Emit 'surchargeUpdate' (if enabled)
    FrontEnd->>PayUI: User clicks Pay Now
    PayUI->>Single API: POST /customers<br/>(name, email from customerRequest)
    PayUI->>Single API: POST /customers/{id}/paymentinstruments<br/>(card token from PayUI)    
    Single API->>PayUI: Return customer and payment instrument
    PayUI->>Single API: Create transaction with customer and payment instrument
    Single API-->>PayUI: Transaction Result and <br/> PaymentRequest state change
    Single API-->>FrontEnd: Emit 'process' event
    FrontEnd->>FrontEnd: Display Processing Result
    Single API-->>Merchant Server: Transaction Webhook
    Single API-->>Merchant Server: Payment Request Webhook

CustomerRequest Properties

The customerRequest object controls tokenisation behaviour:

PropertyTypeRequiredDescription
paymentInstrumentstringNoSet to "create" to create a payment instrument. If omitted, no payment instrument is created.
namestringNoCustomer name. Cannot be used with id. Optional when creating a new customer.
emailstringNoCustomer email. Cannot be used with id. Optional when creating a new customer.

CustomerResult Properties

When tokenisation succeeds, customerResult is populated in the Payment Request response:

PropertyTypeDescription
idstringThe unique customer identifier.
locationstringThe full URL to the customer resource.
paymentInstrumentIdstringThe unique payment instrument identifier.
paymentInstrumentLocationstringThe full URL to the payment instrument resource.

Validation Rules

PayUI validates customerRequest to ensure data consistency:

Identity Rules

  • Creating a new customer:
    When creating a new customer, you can provide name or email, both optional but recommended. The name can be completed from the PayUi form or else it will be defaulted to VALUED CARDHOLDER.

Payment Instrument Creation

  • Explicit opt-in required:
    Payment instruments are only created when paymentInstrument: create is explicitly included in customerRequest.

  • Without paymentInstrument: create:
    If you omit paymentInstrument or set it to any other value, no payment instrument will be created.

Example Validation Errors

Validation errors

CodeMessageReason
V10214payment_request_customer_id_invalidthe provided customer id is invalid
V10215payment_request_customer_email_invalidThe email is either invalid format (valid email, lenght) or was provided in conjuction with id
V10216payment_request_customer_name_invalidThe customer name is either an invalid format or was provided in conjuction with id
V10219payment_request_customer_paymentinstrument_invalidpayment instrument action is one of the allowed values

Using Tokenised Payment Instruments

Once you have stored the customer ID and payment instrument ID, you can use them for future transactions via the standard Transactions API:

Endpoint: POST /transactions

{
"reference": "RECURRING-2026-001",
"category": {
"origin": "internet",
"frequency": "recurring",
"captureType": "auto"
},
"payment": {
"amount": 5000,
"currencyCode": "AUD",
"instrument": {
"customer": {
"id": "e945e8vh0a9szsxig9pohvs9i3lrmw",
"paymentInstrumentId": "JMFEgR2z5EGL7GF7lAcFxA",
"cvn": "123"
}
}
}
}

Note: Including cvn for recurring transactions may improve approval rates and is recommended when available.

Managing Tokenised Instruments

You can manage customer and payment instrument records using the standard API endpoints:

  • Retrieve a customer: GET /customers/{customerId}
  • Update a customer: PUT /customers/{customerId}
  • List payment instruments: GET /customers/{customerId}/paymentinstruments
  • Retrieve a payment instrument: GET /customers/{customerId}/paymentinstruments/{paymentInstrumentId}
  • Update a payment instrument: PUT /customers/{customerId}/paymentinstruments/{paymentInstrumentId}
  • Delete a payment instrument: DELETE /customers/{customerId}/paymentinstruments/{paymentInstrumentId}

For complete documentation on customer and payment instrument management, see the API reference.

Apple Pay Long-Lived Token with Agreement Details

When tokenising an Apple Pay payment instrument, you can include agreementDetails in the Payment Request to establish a long-lived token. This is suitable for subscriptions, or recurring billing, where the customer agrees upfront to ongoing charges.

The agreementDetails object defines the terms of the recurring arrangement, including billing frequency, duration, and a management URL where the customer can view or cancel the agreement. Apple Pay uses these details to generate a long-lived payment token tied to the agreement, allowing you to process future charges without requiring customer interaction each time.

Apple Pay and Google Pay can be used for tokenisation without providing agreementDetails. The agreement details are not mandatory and are only needed when you want to set up a long-lived token for automatic, repeat charges. If you simply want to tokenise the payment instrument for future merchant-initiated transactions, include apple_pay or google_pay in paymentMethods alongside customerRequest with paymentInstrument: create and category.frequncy as recurring, as shown in the examples above.

AgreementDetails Properties

PropertyTypeRequiredDescription
frequencystringNoBilling frequency. Must be one of: daily, monthly, annual when provided.
frequencyCountintegerNoNumber of billing cycles. Must be greater than 0 when provided.
descriptionstringYesA description of the recurring arrangement shown to the customer. Maximum 140 characters.
startDatestringNoStart date in yyyy-MM-dd format. Defaults to today if not provided.
endDatestringNoEnd date in yyyy-MM-dd format.
amountintegerNoThe recurring charge amount in the lowest denomination (e.g. cents). Defaults to 0 if not provided.
managementURLstringYesA URL where the customer can manage or cancel the agreement.
billingAgreementstringNoA customer-facing summary of the billing terms. Maximum 140 characters.

Example: Payment Request with Agreement Details

{
"reference": "SUB-2026-001",
"payment": {
"amount": 4000,
"currencyCode": "AUD",
"description": "Monthly Subscription"
},
"paymentMethods": ["apple_pay"],
"transactionRequest": {
"category": {
"frequency": "single",
"captureType": "auto"
}
},
"customerRequest": {
"paymentInstrument": "create",
"name": "Jane Doe",
"email": "jane.doe@example.com"
},
"agreementDetails": {
"frequency": "monthly",
"frequencyCount": 12,
"description": "Monthly Subscription",
"startDate": "2026-05-10",
"endDate": "2026-10-10",
"amount": 4000,
"managementURL": "https://merchant.example.com/manage",
"billingAgreement": "You will be charged each month until you cancel."
}
}

Best Practices

Testing

Test tokenisation in the sandbox environment:

  1. Create a Payment Request with customerRequest including paymentInstrument: create
  2. Complete the payment using sandbox test card numbers
  3. Verify customerResult is populated with customer and payment instrument IDs
  4. Test subsequent transactions using the tokenised payment instrument

For sandbox card numbers and testing scenarios, see Testing Introduction.

Troubleshooting

customerResult is null or missing when trying to tokenise

  • Verify paymentInstrument: create was included in customerRequest

Payment instrument not created

  • Ensure paymentInstrument: create is explicitly included in customerRequest
  • Omitting this field or using any other value will prevent payment instrument creation

Subsequent transactions fail with tokenised instrument

  • Verify the customerId and paymentInstrumentId are correct
  • Check that frequency: recurring is set for recurring transactions
  • Include cvn when available to improve approval rates