> ## Documentation Index
> Fetch the complete documentation index at: https://developers.paychoice.com.au/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Token page

> A hosted page that captures a card or bank account and returns a token to your page, without the details touching your systems.

The Create Token page is the tokenisation counterpart of the [Widget](https://developers.paychoice.com.au/taking-payments/widget.md): a PayChoice-hosted form in an iframe that stores the card or bank account and hands your page the token. Use it when you want to keep a payment method on file — for a subscription, say — without charging it immediately.

## Embed it

| Environment | Base URL |
| - | - |
| Sandbox | `https://sandbox-spa.paychoice.com.au` |
| Production | `https://spa.paychoice.com.au` |

* Credit card: `{baseURL}/tokenization/card/{merchant_guid}`
* Bank account: `{baseURL}/tokenization/bank/{merchant_guid}`

Only the merchant GUID is needed; there's no public key.

**iframeId** `string`

Any string, echoed back as `iframe_id` in every message, so you can tell iframes apart when a page has several.

```html theme={null}
<iframe
  height="400"
  width="600"
  src="https://sandbox-spa.paychoice.com.au/tokenization/card/315564b9-b863-4016-8c53-02c9d8cc80b7?iframeId=card-1"
  frameborder="0">
</iframe>
```

The form shows the methods enabled for your merchant account. On the card form, name, number and expiry are required; CVV is optional. On the bank form, name and account number are required, plus BSB for Australian merchants.

## Receive the token

Results are sent to `window.parent` via `postMessage`. **Always check `event.origin`** against the base URL you embedded. Every message uses the same envelope:

```json theme={null}
{
  "message": "Token was Created",
  "timestamp": "2024-12-15T23:50:20.069Z",
  "status": "success",
  "data": {
    "card_name": "John Doe",
    "card_type": "Visa",
    "expiry_month": "12",
    "expiry_year": "27",
    "link": { "href": "/api/v5/token/123e4567-e89b-12d3-a456-426614174000", "rel": "self" },
    "masked_number": "411111XXXXXX1111",
    "token": "123e4567-e89b-12d3-a456-426614174000",
    "key_id": 1,
    "bin": {
      "bin-number": "411111",
      "card-brand": "VISA",
      "card-category": "CLASSIC",
      "card-type": "DEBIT",
      "is-commercial": false,
      "is-prepaid": false,
      "issuer": "TEST BANK",
      "country": "AU",
      "valid": true,
      "first-six-digits": "411111"
    }
  },
  "code": 200,
  "iframe_id": "card-1"
}
```

| Case | `status` | `message` | `code` | `data` |
| - | - | - | - | - |
| Token created | `success` | `Token was Created` | 200 | The card object (with a `bin` lookup) or the bank object |
| Token could not be created | `error` | `Unable to create token` | 500 | `{ "statusCode": 500, "message": "Unable to get token" }` |
| Page could not load | `error` | e.g. `Invalid merchant`, `No tokenisation methods are available for this merchant` | 200 | `null` |

```javascript theme={null}
const PAYCHOICE_ORIGIN = 'https://sandbox-spa.paychoice.com.au';

window.addEventListener('message', (event) => {
  if (event.origin !== PAYCHOICE_ORIGIN) return;
  const msg = event.data;
  if (!msg || !('status' in msg)) return;

  if (msg.status === 'success') {
    const token = msg.data.token ?? msg.data.bank_token;
    // Send the token to your server and attach it to the customer.
  } else {
    console.warn('Tokenisation failed:', msg.message);
  }
});
```

## Then attach it

The page stores the token but doesn't link it to a customer. Send the token to your server and [attach it to the customer](https://developers.paychoice.com.au/billing/payment-methods.md) so it persists and can be used for subscriptions and invoices; otherwise it expires after first use like any other [token](https://developers.paychoice.com.au/storing-payment-methods/tokens.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.