Skip to content

Powered by Grav CMS + Helios Theme

Payment providers

The registered payment providers, and the operator actions against one.

The payment providers this store offers, and the operator actions against one. Configuration itself stays in each provider plugin's own Grav blueprint.

List payment providers

GET /api/v1/kahunacart/providers Permission kahunacart.settings

Every registered payment method with its label, the capabilities it declares, whether it can be connection-checked, whether it can register its own webhook endpoint, whether it syncs products, what automatic sync is configured to do, and which one checkout starts on. Each also carries last_check (the kept answer of its last check_provider, or null), deliveries (its webhook log totals, last arrival and failure streak, or null when none has arrived) and webhook_mode (endpoint, per_payment or none). A store that sells in more than one currency also gets currency_coverage: for each currency it sells in, base first, the payment methods that take it (slug to name), and an empty list means a shopper in that currency cannot check out. Credentials live in each provider plugin's own settings and are never reported here.

Response

Answers {providers: [{slug, label, capabilities, can_check, can_setup_webhook, is_default, can_sync, sync_direction}]}. No credential ever appears in a response.

Check a provider's connection

POST /api/v1/kahunacart/providers/{slug}/check Permission kahunacart.settings

Ask a payment provider to prove the credentials already configured for it actually work, and report what it resolved, such as the account and the environment. Where the driver can, it also looks up this store's webhook endpoint at the platform, changing nothing. state is ok, warning or failed: warning is a check that passed with something wrong in the webhook (no endpoint, switched off, missing events, or three failed deliveries in a row), each spelled out in warnings. The answer is kept and shown on the Payments card. A failing check is a successful call: it answers 200 with ok false and the provider's own message. The error statuses are kept for a provider that cannot be asked at all, which is a different thing a merchant needs told apart.

Parameters

Name Type Description
slug required string Provider slug, from list_providers

Sync the catalog with a provider

POST /api/v1/kahunacart/providers/{slug}/sync Permission kahunacart.settings

Push this store's catalog to a payment provider, or pull the provider's into it, and report how many products moved. Push is the default because it only restates what this store already believes; pull rewrites local products from the provider's copy and has to be asked for by name. The provider's configured automatic sync direction is not consulted, so a merchant can sync once without committing to syncing forever. A network or API failure answers 200 with ok false and the provider's message. A pull skips any price the provider reports in a currency other than the store's base currency and says how many in skipped_prices, a key that is only there when something was skipped.

Parameters

Name Type Description
slug required string Provider slug, from list_providers
direction optional string pull rewrites local products from the provider's copy
One of: push, pull
Default: push

Set up a provider's webhook

POST /api/v1/kahunacart/providers/{slug}/webhook Permission kahunacart.settings

Ask a provider to register this store's webhook endpoint with it, subscribed to exactly the events it handles, and write whatever signing secret comes back into that provider's own plugin settings. The secret goes to disk and is never returned. The response also names endpoints registered against this store's route at a different address, which is the residue a site leaves behind when it moves off a tunnel or out of staging. Send reset true to delete this store's existing endpoints and register afresh, which is also how a signing secret is rotated on a platform that will not disclose one twice.

Parameters

Name Type Description
slug required string Provider slug, from list_providers
reset optional boolean Delete this store's existing endpoints on the provider first, then register
Default: false

Make a provider the default

POST /api/v1/kahunacart/providers/{slug}/default Permission kahunacart.settings

Write checkout.default_provider so checkout starts on this payment method. Stored against the store rather than the provider, because two stores running the same provider disagree about it. A configured slug that is not registered, or one filtered out because the cart holds something shippable, falls back to the first method actually offered.

Parameters

Name Type Description
slug required string Provider slug, from list_providers

List a provider's card readers

GET /api/v1/kahunacart/providers/{slug}/readers Permission kahunacart.settings

The card readers on a payment provider's account, as the provider reports them now: each with its id, the label it was given, its status (online, offline or busy), its model and the provider's location reference, and how the provider pairs readers: pairing device_code (the reader shows a code, send it with pair_provider_reader) or app_code (get a code with begin_reader_pairing and type it into the reader). The store keeps no list of readers of its own. 422 for a provider that cannot take a card on a reader, 404 for one that is not registered.

Parameters

Name Type Description
slug required string Provider slug, from list_providers; it must declare card_present

Pair a card reader

POST /api/v1/kahunacart/providers/{slug}/readers Permission kahunacart.settings

Register a card reader with a payment provider from the code the reader shows on its screen (a Stripe registration code, a SumUp pairing code), and answer the reader. For a provider whose readers take a code instead (pairing app_code on list_provider_readers, like Square) use begin_reader_pairing. A code the provider will not pair answers 422 with the provider's own sentence.

Parameters

Name Type Description
slug required string Provider slug, from list_providers
code required string The code the reader shows
label optional string What to call the reader, like Front counter
location_ref optional string The provider's own location for the reader, when it has such a thing

Get a code to pair a card reader

POST /api/v1/kahunacart/providers/{slug}/readers/pairing Permission kahunacart.settings

For a provider whose readers pair from a code the provider makes (pairing app_code on list_provider_readers, like Square): ask the provider for a code, and answer the pairing with its id, the code to type into the reader, its status (waiting) and when it expires. Then read get_reader_pairing until it says paired. 422 for a provider whose readers show their own code (use pair_provider_reader) or when the provider refuses, with its sentence.

Parameters

Name Type Description
slug required string Provider slug, from list_providers
label optional string What to call the reader, like Front counter
location_ref optional string The provider's own location for the reader, when it has such a thing

Read a card reader pairing

GET /api/v1/kahunacart/providers/{slug}/readers/pairing/{pairing} Permission kahunacart.settings

How a pairing from begin_reader_pairing stands: waiting for the code to be typed into a reader, expired (start again), or paired, with the reader that took it. A read: nothing changes. 404 when the provider has no pairing by that id.

Parameters

Name Type Description
slug required string Provider slug, from list_providers
pairing required string The pairing id begin_reader_pairing answered

Remove a card reader

DELETE /api/v1/kahunacart/providers/{slug}/readers/{reader} Permission kahunacart.settings

Take a card reader off a payment provider's account. 404 when no reader by that id is on the account.

Parameters

Name Type Description
slug required string Provider slug, from list_providers
reader required string Reader id, from list_provider_readers

Take a card payment on a reader

POST /api/v1/kahunacart/orders/{id}/reader-payments Permission kahunacart.orders.manage

Put an amount on a card reader for an order and come back at once with the payment pending; the customer then taps, inserts or swipes on the reader. The amount may be less than the order owes, and the order is then part paid and the rest can be paid another way; it may not be more. Send the same idempotency_key on a retry and the payment already started is answered instead of a second one. The status is pending, or checking when the provider's answer never came back (nothing is known yet; it is sent again under the same key by refresh_reader_payment). 409 when the order is already paid or cancelled, owes nothing, already has a card payment waiting on a reader, or has a checkout open online that could still be paid (unless the order is paid in parts); 422 for an amount over what is owed, a provider that cannot take a card on a reader, or a reader that refused the payment, with the reason. Then call refresh_reader_payment every couple of seconds while the status is pending, checking or cancelling.

Parameters

Name Type Description
id required integer Order id
provider required string Provider slug; it must declare card_present
reader required string Reader id, from list_provider_readers
amount_minor optional integer What to take, in minor units of the order currency
amount optional string What to take as a decimal string, like "12.50", when amount_minor is not sent
idempotency_key optional string The same string on a retry of the same payment, at most 128 characters

Read a card reader payment

GET /api/v1/kahunacart/orders/{id}/reader-payments/{tid} Permission kahunacart.orders.manage

How a card payment on a reader stands as the store has it: pending, checking, cancelling, succeeded, failed (with the reason in plain words), cancelled or timed_out, with the amount, the reader, the provider's reference and order_settled (false while the money is recorded and the order is still being completed). A read: the provider is not asked and nothing changes; refresh_reader_payment asks it.

Parameters

Name Type Description
id required integer Order id
tid required integer The transaction_id start_reader_payment answered

Refresh a card reader payment

POST /api/v1/kahunacart/orders/{id}/reader-payments/{tid}/refresh Permission kahunacart.orders.manage

Ask the provider how a card payment on a reader stands and apply the answer exactly as its webhook would, so a store the provider cannot reach still settles; then answer the payment. A start whose answer never came back is sent again under the same idempotency key. A payment whose money is recorded and whose order could not be completed yet is completed again (and a job is booked to keep trying). Safe to call as often as needed and at the same moment as the webhook. What a till calls every couple of seconds while the status is pending, checking or cancelling.

Parameters

Name Type Description
id required integer Order id
tid required integer The transaction_id start_reader_payment answered

Cancel a card reader payment

POST /api/v1/kahunacart/orders/{id}/reader-payments/{tid}/cancel Permission kahunacart.orders.manage

Clear the reader while the payment is still pending, because the customer changed their mind or the wrong amount was sent. Answers the payment as cancelled when the provider confirmed it, or cancelling when it only took the request (keep calling refresh_reader_payment until it is cancelled or succeeded). A payment that has already finished is answered as it stands. 409 when the provider could not cancel it, which usually means the customer had just paid, or could not be reached: refresh it in a moment.

Parameters

Name Type Description
id required integer Order id
tid required integer The transaction_id start_reader_payment answered

Give up on a card reader payment

POST /api/v1/kahunacart/orders/{id}/reader-payments/{tid}/abandon Permission kahunacart.orders.manage

Give up on a card payment on a reader that the provider cannot say anything about: a start whose answer never came back (checking), or a payment whose provider cannot be reached. It blocks every other reader payment and pay link on the order until somebody hears back, and this is the way out. The provider is asked once more first. When that settles the payment either way it is answered as it now stands and nothing is given up; when the provider answers that the payment is still on the reader it is 409 (cancel_reader_payment instead). Only when it still cannot say is the payment failed, with a history entry saying who gave up on it, and the order can then be paid another way. The customer may still have been charged: a completion that arrives later is recorded on the order as it would be after a cancel.

Parameters

Name Type Description
id required integer Order id
tid required integer The transaction_id start_reader_payment answered

check and sync always answer 200 when the provider answered at all. A failing check is a successful request reporting a failure, and the provider's own words are what a merchant needs. sync answers {slug, direction, ok, count, summary}, and a network failure comes back as ok: false with the exception's message rather than a 500. A provider that cannot be asked at all is a 422; a slug nothing registers is a 404.

webhook takes an optional {reset: true}, which deletes this store's existing endpoints before registering. Whatever signing secret comes back is written to the provider plugin's config file and never returned to the caller. default writes checkout.default_provider on the base plugin. Configured sync direction is not consulted by sync: off means "do not sync automatically", not "refuse an operator who asked".