Skip to content

Payment Tokens

Every successful payment auto-creates a reusable token (pt_…). This page covers the read + revoke endpoints for tokens already on file. To create a token by importing an existing gateway token, see Tokenization.

Tokenize vs Payment Tokens

  • POST /tokenize — import an existing gateway-side token under a customer (used by integrators migrating off another processor).
  • GET /customers/{external_customer_id}/payment-tokens — list cards already saved through normal checkout flows.
  • POST /payment-tokens/{id}/deactivate — revoke a token so it can't be charged again.

None of these endpoints capture a card from scratch. A new card is always tokenized through a checkout session.

Token statuses

StatusMeaning
activeEligible for POST /charge-token and for use on subscriptions.
inactiveRevoked by the merchant or the customer. Cannot be charged.
expiredPast expiry_month / expiry_year. Cannot be charged.

A token also goes inactive automatically when the underlying gateway flags it as unusable (e.g., chargeback / fraud lock).

List saved cards for a customer

http
GET /api/v1/customers/{external_customer_id}/payment-tokens

{external_customer_id} is the merchant-side customer id (your wp_users.ID, your Magento customer_id, your Shopify customer_gid). Genius Checkout maps it during the first checkout — storefront plugins do this automatically.

Response (200)

json
{
  "data": [
    {
      "id": "pt_xyz789",
      "brand": "visa",
      "last4": "4242",
      "expiry_month": "12",
      "expiry_year": "2030"
    }
  ]
}

If the customer has never paid through Genius Checkout, the response is {"data": []} (200, not 404) so storefront UIs can render the saved-card section unconditionally.

The encrypted token is never returned — use the id (pt_…) to reference the token in POST /charge-token or POST /subscriptions.

Deactivate a token

http
POST /api/v1/payment-tokens/{external_id}/deactivate

Idempotent — calling it on an already-inactive token returns 200 with the current state. Use this when:

  • A customer cancels their subscription on your merchant side and you want to revoke the saved card.
  • A fraud signal on your end means the card should no longer be billable.
  • You're cleaning up after account-deletion / right-to-erasure flows.

Response (200)

json
{
  "id": "pt_xyz789",
  "status": "inactive",
  "brand": "visa",
  "last4": "4242"
}

Code samples

bash
# Render a saved-card picker on your storefront
curl -H "Authorization: Bearer $GC_API_KEY" \
  "https://app.geniuscheckout.com/api/v1/customers/wp_user_42/payment-tokens"
js
// Node — revoke after a subscription cancel
await fetch(`https://app.geniuscheckout.com/api/v1/payment-tokens/${tokenId}/deactivate`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.GC_API_KEY}`,
    'Idempotency-Key': crypto.randomUUID(),
  },
})
python
# Python — list a customer's saved cards
import requests
r = requests.get(
    f"https://app.geniuscheckout.com/api/v1/customers/{external_id}/payment-tokens",
    headers={"Authorization": f"Bearer {GC_API_KEY}"},
)
cards = r.json()["data"]

Security notes

  • API keys are scoped to a single merchant. A request with one merchant's key can never see or revoke another merchant's tokens — cross-merchant lookups return data: [] or 404, never the existence of the resource.
  • Saved cards are never exposed in browser-facing code. Storefront plugins fetch the list from PHP / server-side, then render only {id, brand, last4, expiry_*} to the page. The encrypted token stays on the GC platform.

Next

Released under the proprietary Genius Checkout license.