Create a Payment Intent

The one server-side call that starts a Flow session and returns a browser-safe token.

DEVELOPER GUIDE

Create a Payment Intent

The one server-side call that starts a Flow session and returns a browser-safe token.

A Payment Intent starts a Flow session. You create it from your backend with your secret API key. In the request, give the agreement and the payment you want to take. The response is the first Result: a token and the first action for the widget to run.

This is the only call you make directly. The widget makes every call after it.

Create the intent

POST /embed/create-payment-intent
Authorization: Bearer <your-secret-api-key>
Content-Type: application/json

Request Example

{
  "client_id": "019efd1237de70d1b69bae4f1c48d170",
  "type": "PayTo.Debtor.OneTimePayment",
  "data": {
    "agreement": {
      "uid": "biz_agreement_G7MQWwkQZIP8vbfH",
      "purpose": "retail",
      "description": "Payment plan for order #1234",
      "creditor": {
        "party_name": "Zeptinghouse Pty Ltd",
        "ultimate_party_name": "Zeptinghouse Pty Ltd",
        "account_identifier": {
          "type": "bban",
          "bsb": "062000",
          "account_number": "12345678"
        }
      }
    },
    "payment": {
      "uid": "biz_20221231_G7MQWwkQZIP8vbfH",
      "amount": 2495,
      "reference": "Order 1234"
    }
  }
}

Response 201

{
  "token": "eyJhbGci…",
  "action": {
    "name": "collect-debtor-details",
    "path": "/payto/debtor/one-time-payment/create-agreement"
  }
}

Return { token, action } to your checkout page and hand it to the widget. See Mount the widget.

The token is opaque and browser-safe

Treat token as an opaque string scoped to this one Payment Intent. Pass it to your page unchanged. Do not parse, log, or persist it beyond that.

Request fields

FieldRequiredDescription
client_idYesYour client identifier: 32 characters, RFC 3986 unreserved characters (A-Z a-z 0-9 _ ~ . -).
typeYesThe flow to run. Currently PayTo.Debtor.OneTimePayment.
data.agreementYesThe PayTo agreement to create. See below.
data.paymentYesThe payment to take against the agreement. See below.

agreement

FieldRequiredDescription
uidYesYour unique identifier for the agreement (≤64 chars, RFC 3986 unreserved). Ensures uniqueness between your system and Zepto.
purposeYesNature of the agreement: retail, loan, utility, mortgage, salary, personal, government, pension, tax, dependant_support, gambling, or other.
descriptionYesNarrative reason for the agreement (≤140 chars, ASCII printable).
creditorYesThe party that receives the payment: party_name, ultimate_party_name, and an account_identifier (see alias resolution when you use PayID).
resolution_requested_beforeNoISO-8601 UTC deadline for the payer to accept. Defaults to 10 minutes from creation.
cancel_if_unresolvedNoAuto-cancel if not authorised by resolution_requested_before. Needs that field to be set.
metadataNoYour custom data (flat object, ≤2 kb). Zepto echoes it in webhook payloads under resource_metadata.

payment

FieldRequiredDescription
uidYesYour unique identifier for the payment (≤64 chars, RFC 3986 unreserved).
amountYesAmount in cents (integer). 2495 is $24.95 AUD.
referenceNoFree-form text for reconciliation. It usually appears on both parties' bank statements.
descriptionNoLonger free-form text that helps to match the payment (≤280 chars).
metadataNoYour custom data (flat object, ≤2 kb).

Amounts are in cents

amount is an integer number of cents, not dollars. Send 2495 for $24.95, not 24.95.

Validation errors

If the request is invalid, you get a 422 response. It contains an errors array that shows what to fix:

{
  "errors": [
    { "title": "Invalid client_id", "detail": "The client_id provided is not valid", "code": "E100" }
  ]
}

Next steps

Mount the widget with the { token, action } you just received.


Did this page help you?