Getting started

What to expect

Where HansaPay behaves differently from what an existing integration may assume. Read this before you integrate.

Read this section first, whether you are integrating for the first time or moving an existing integration to HansaPay.

The request and response formats in this document may already be familiar to you, and an integration built for them will work without code changes. That is exactly why this section matters. When HansaPay behaves differently from what your code assumes, nothing fails loudly: there is no new field, no schema error, no 404. The difference shows up as a different amount, a different status or an error you have not seen before. Each item below is such a case.

Card amounts can be rounded down to a price point

Some card channels only accept a fixed list of prices. When your order goes to one of them, HansaPay rounds the amount down to the nearest price point and charges that.

  • The rounding only happens when the drop is 5% or less. For example, 12.50 USD is charged as 11.99 USD, but 17.50 USD and 75.00 USD cannot be rounded (the nearest points are more than 5% lower).
  • If no channel available to you can take the amount, the order is refused with 2006 Amount is out of the allowed range.
  • trans_amount reports the amount actually charged. requested_amount carries the amount you asked for, and is present only when rounding happened. See Price points for which responses carry it.
  • Webhooks report the charged amount. If your reconciliation matches a webhook to an order by amount, it will not match. Match on order_no or merchant_order_no, never on amount.

Apple Pay and Google Pay have always worked this way on the same channels. What is new is that card payments can now be rounded as well.

Suspended merchant accounts are refused new payments

If HansaPay suspends your merchant account, new money movement is refused until the suspension is lifted:

  • /payments/create and /payments/checkout return code 1001 with the message merchant account is disabled|merchantFrozen.
  • Payment links stop accepting payments, and portal actions that create or move money are disabled.

Everything else keeps working: authentication, /payments/query, refunds, webhooks for existing orders, and settlement of money already collected. The suspension check runs after the request itself has been validated, so a request that is also invalid in another way reports that problem first.

Some payment methods are accepted but not currently available

The API accepts these payment_method values: CARD, APPLE_PAY, GOOGLE_PAY, CASH_APP, PAYPAL and PIX. Not all of them can be processed today.

payment_methodAvailable
CARDYes, when a card channel is enabled for your account
APPLE_PAY, GOOGLE_PAYYes, when enabled for your account
CASH_APPYes, when enabled for your account
PAYPALNo
PIXNo

A request with an unavailable method passes validation and then fails with code 3003, for example payment_method PAYPAL is not available|paymentMethodUnavailable. The same error is returned for a method that exists but is not enabled for your account.

Card payments are charged in USD. Orders in another currency are converted first; see Amounts and currency.

Card refunds are full refunds and are reviewed before they complete

On card, Apple Pay and Google Pay payments:

  • Only a full refund is possible, and only one refund per payment. A partial refund is refused with This payment channel does not support partial refunds; only full refunds are allowed.
  • Every refund is reviewed before the money is returned. A refund starts as PENDING and becomes SUCCESS or FAILED later; there is no guaranteed time. You receive a refund.updated webhook when it changes.
  • A refund number that was refused cannot be reused. See Idempotency.

Cash App refunds complete immediately and can be partial.

Payouts are not currently offered

The /payouts/* endpoints are documented in full in Payouts, but no payout method is available today. Every valid payout request returns 5007, for example payment_method CASH_APP is not available for payouts|unsupportedPayoutMethod. Nothing is created and no balance is held.

To take money out of your HansaPay balance, request a withdrawal in the merchant portal. Withdrawals carry a fee and go to a receiving account that HansaPay has verified; see the Merchant Guide.

Chargebacks are not sent as webhooks

When a payer's bank reverses a payment (a chargeback), HansaPay records it and debits your balance, but no webhook is sent. The original payment's status does not change either. Chargebacks appear only in the merchant portal, under Chargebacks. Check that screen regularly, or ask your account manager about other ways to be told.

Responses and webhooks can report different amounts

For an order in a currency other than USD, API responses report the amount and currency you sent, while payment.updated and refund.updated webhooks report the USD amount that was charged. For USD orders the two are the same. See Amounts and currency for a worked example.

Error messages are English, with a stable key

Error messages are in English and end in a stable key, for example Order not found|orderNotFound. Only a known set of messages is passed on; any other failure is reported as System busy, please try again later|systemBusy. This includes some errors you can fix yourself, such as an invalid card number. See Errors.

Other behaviour to know

  • Upstream reference numbers are not returned. Responses and webhooks carry HansaPay's order_no and your own numbers only.
  • A payment for the wrong amount is not marked paid. If the provider reports a paid amount that differs from the order amount, the order does not become SUCCESS, whether the difference is reported by webhook or found by a query.
  • Payment links have no API. They are created and managed in the merchant portal only. See Not available through the API.