Skip to main content

Demo Site

ecom-php-demo.kody.com is a working PHP store running against staging. Every page shows the request it sent, the response it got, and the code that produced it, in PHP, Java, Python and .NET.

Use it two ways: click through a flow before you write anything, and keep it open beside your own build to compare a call that is not behaving.

Before you click

EnvironmentStaging only
Default Store IDc4cebf51-b006-4bb9-acd5-bb4bcdbd6e09
Your own storeSettings → paste your staging Store ID and API key; Reset restores the defaults
Terminal paymentsNeed your own store with a terminal assigned to it — see Terminals
AmountsMinor units — 2000 is GBP 20.00
CurrenciesGBP, HKD, USD

The default store is shared with every other reader, so its transactions and saved cards are not yours. Point the store at your own staging credentials as soon as you have them — it is also the only way to see your own terminals.


Online Payment Demo

Try it on staging →
Reference: Online Payments

A full hosted-page payment: create a payment link, pay on Kody's page, land back on the store, confirm.

  • Set your own order ID in the form. That is the reference that comes back to you, and the key you will join your ledger on.
  • Watch the redirect: it returns as a bare ?order=ORD-xxxx. No status parameter. The demo resolves the outcome with a server-side PaymentDetails call — do the same, and mark nothing paid before it answers.
  • The payment_url is single-use. Re-initiate rather than re-showing an old link.

Checkout Component In Iframe

Try it on staging →
Reference: Checkout Component

The same payment, embedded, so the customer never leaves the page.

  • Same InitiatePayment call, plus isEmbeddedInIframe=1 on the URL.
  • The iframe needs allow="payment" and an explicit height, and your domain has to be allowlisted by Kody. Request that on day one — it has a lead time, and until it lands the frame renders blank.
  • The page listens for PAYMENT_COMPLETE. Verify the origin, then still confirm server-side: a browser message can be forged.
  • A blank frame is almost always one of four things — domain not allowlisted, missing allow="payment", no height set, or a stale payment URL.

Terminals

Try it on staging →
Reference: Terminal Payments

Lists every terminal on the store with its online status, in the S1F2-000… serial format you will pass as terminal_id.

Use your own store for terminal payments

The terminals on the shared demo store are not yours, so you cannot present a card on them. Before you try a terminal payment, switch Settings to your own staging Store ID and API key, with a terminal assigned to that store. Without that, the request may be accepted but no card can ever be read.

  • Check the terminal is online before you initiate. An offline terminal fails the payment, not the request.
  • Wait for Orders must be enabled on the terminal or it will not accept an API-initiated payment.
  • Terminal payments are read back with PaymentDetails by order ID — GetPayments lists online payments only.

No terminal on your store? Email integrations@kody.com with your staging Store ID and the model you need (S1F2 or AMS1).


Token Payment

Try it on staging →
Reference: Tokenised Payments

Saves a card, then charges it with the customer not present.

  • payer_reference is yours to choose and the only handle on the saved card. Use a stable internal customer ID — not an email address or phone number, which change.
  • Create the token when the customer consents, not silently on every payment.
  • A token can come back PENDING_CREATE. Treat it as not yet usable and read it again rather than charging it.
  • A card saved at a terminal can be charged online and the reverse. Pick the call by what you want to happen, not by where the card came from.

Card Tokens

Try it on staging →
Reference: Tokenised Payments

Loads the saved cards for a payer_reference and deletes one.

  • Enter the same payer_reference you saved with — the list is scoped to it, so a mismatch looks like data loss and is not.
  • Delete on request, and handle the card expiring. Kody holds the card details; you hold nothing but the token.

All Transactions

Try it on staging →
Reference: Online Payments

Online payment history for the store, with status and refunds.

  • Match what you see here against your own order records. Any row you cannot map to an order is the gap your order_id was supposed to close.
  • A refund must be sent with the store_id that took the payment. Payments cannot be refunded from another store.
  • On the shared demo store this list belongs to everyone. Use your own store to read your own payments.

View Logs

Try it on staging →
Reference: Overview

The raw request and response behind everything above.

  • The fastest way to debug your own integration: run the flow here, then diff your payload against the one that worked.
  • Field names and shapes are exact. amount_minor_units, not amount.

Then make it fail

Success paths are the easy half. In person, the last three digits of the amount select the response; online and MOTO turn on whether the expiry date and security code are entered correctly. Which amount produces which refusal, and the card numbers, are on Test Cards.

Work through at least one decline, one cancellation and one pending payment before you go live. All three are normal outcomes, and all three reach your code as a PaymentStatus you have to handle.