Changelog

Platform updates, new features, and fixes.

October 5, 2026v3.43
  • improvedThe Gift Card docs now spell out what to deliver for a short payment: grant only on payment.completed, for amount, and how to turn that amount into credits from your own packs. See Gift Card → What to deliver.
October 5, 2026v3.42
  • improvedPart-paid gift card orders now complete for every merchant when the 24-hour window ends. Your balance is credited the received amount minus fees, and payment.completed fires with amount set to the received amount and amount_requested set to the order amount. You can still click Accept before the window ends. Orders under $2 still expire and are not credited. Delivering what amount is worth, including when it is less than the order, is part of offering gift cards. The "Settle part-paid gift card orders automatically" setting has been removed.
October 5, 2026v3.41
  • newOrders that fall between gift card amounts can be paid with the next smaller card. Turn on "Accept the next smaller gift card" under Settings → Payment Methods → Gift Card and checkout offers that card when it is at most $5 short: a $12 order is offered the $10 card, a $16 order the $15 card. Redeeming it completes the order at the card's value, and payment.completed carries amount set to what was received and amount_requested set to the order amount. A gap over $5 (a $50 card on a $60 order) is not offered, and a smaller card than the one offered stays a part-payment. Off by default. Turn it on only if your webhook handler fulfils based on amount, and leave gift_card_amount unset so checkout can pick the face.
October 4, 2026v3.40
  • newPart-paid gift card orders can now settle without a click. Turn on "Settle part-paid gift card orders automatically" under Settings → Payment Methods → Gift Card and an order whose codes cover only part of it completes at the received amount when its 24-hour window runs out: you get payment.completed with amount set to the received amount and amount_requested set to the order amount, instead of payment.expired. Off by default; turn it on only if your webhook handler fulfils based on amount rather than the order it created.
  • improvedGET /api/v1/payments/{id} now reports gift_card.amount_received and, while the order is still short, gift_card.amount_remaining (USD), so you can see a part-payment without the webhook.
  • improvedThe Partial payments and Gift Card docs now say explicitly to fulfil only on payment.completed, for amount: payment.partial and payment.expired are information only, and the customer may still pay the rest.
October 4, 2026v3.39
  • newPart-paid gift card orders now work like underpaid crypto payments. When a customer's code is worth less than the order and the order is still short, your webhook receives payment.partial with status partially_paid, the order amount and amount_received. If the customer never adds another code, the order shows as Partially paid on your Payments page (open or expired) and account owners and admins can click Accept to complete it at the received amount: your balance is credited that amount minus fees, and payment.completed fires with amount set to the received amount and amount_requested holding the order amount. GET /api/v1/payments/{id} shows amount_requested too.
  • improvedpayment.expired for a gift card order that was part-paid now includes amount_received, so your handler can tell it apart from an abandoned checkout. Until now these orders expired with a plain payment.expired and the customer's payment was not visible to you.
October 4, 2026v3.38
  • newYou can now accept an underpaid crypto payment yourself. When a customer sends less than the invoice (for example because their exchange took a withdrawal fee), the payment shows as Partially paid on your Payments page, with a banner when any are waiting. Click Accept to complete it at the amount the customer actually sent: your balance is credited for that amount minus fees, and you take the shortfall. Your webhook receives payment.completed with amount set to the received amount and a new amount_requested field holding the original invoice amount. GET /api/v1/payments/{id} shows amount_requested too. Only account owners and admins can accept.
  • fixThe docs said crypto payments within 5% of the invoice settle as completed. The real tolerance is 1%: a larger shortfall leaves the payment partially paid and sends payment.partial. The docs now say 1% and describe payment.partial.
October 3, 2026v3.37
  • improvedGift Card fees are lower: 14% + $1 per transaction, down from 16% + $1. The new rate applies to every gift card payment that completes from today, including checkouts opened earlier. Your Fee Schedule, the docs and monthly fee statements show the new rate. Reseller pricing is unchanged.
October 2, 2026v3.36
  • fixGift card codes worth less than the order no longer go to waste. Until now such a code was used up and the order was still not paid, so the customer lost the code's value. Now every accepted code counts toward the order: the checkout tells the customer how much was received and how much is left, keeps the order open for 24 hours, and completes it once the codes entered cover the total. A code bought in another currency that lands slightly under the order total after conversion (up to 5% of the order, at most $2) completes the order as paid, and you receive the full order amount.
  • improvedThe gift_card object on GET /api/v1/payments/{id} reports last_result partially_paid while a customer has paid part of the order with gift card codes and still owes the rest. value_too_low is no longer returned for new attempts.
October 2, 2026v3.35
  • newGET /api/v1/payments/{id} now includes a gift_card object for gift card checkouts: attempts, last_result (processing, redeemed, rejected, manual_review or expired), last_reason when rejected (invalid_code, malformed_code, code_not_redeemable or value_too_low) and last_attempt_at, so your support can tell a customer why their code was not accepted.
  • improvedWhen a customer pastes a gift card code that was already checked and not accepted, the checkout now says so, instead of saying the code was already used.
October 1, 2026v3.34
  • improvedWhile WeChat Pay is temporarily unavailable, payments you create through the API with payment_method WXPAY are created as Alipay: the customer gets an Alipay QR code, and the payment's GET response and webhooks report payment_method alipay. No integration change is needed, and WXPAY orders go back to WeChat Pay automatically once it returns.
October 1, 2026v3.33
  • fixGCash and Maya (Philippines) payments work again. Since September 24 they failed unless the customer's details were included; they now need the customer's mobile number, email address, and name. On the hosted checkout, customers in the Philippines are asked for whichever of these you did not send. On POST /v1/payments with currency PHP, send customer_phone (09…, +63… or 639… are accepted), customer_email and customer_name (first and last name). Without a phone the call returns 422 CUSTOMER_PHONE_REQUIRED, without an email 422 CUSTOMER_EMAIL_REQUIRED, so a payment is never created that cannot be paid.
  • improvedWeChat Pay is temporarily not offered on the hosted checkout; customers in China are offered Alipay. Payments you create through the API with payment_method WXPAY are not affected.
  • improvedPayout wallet wording. Onboarding now labels the field "Payout wallet address (EVM)" instead of "USDC Wallet Address (Polygon)", and onboarding, Settings and the docs list the coins and networks on-ramp payments actually arrive in: USDC or POL on Polygon; PYUSD, USDC or ETH on Ethereum; USDC on Base; BNB on BNB Chain. Use a self-custody EVM wallet — exchange deposit addresses often credit only some of these.
  • fixThe China Pay entry on the Payment Providers page said Alipay and WeChat Pay settle as USDT. They settle in CNY to your balance, which you withdraw in the crypto you choose at the day's rate.
September 29, 2026v3.32
  • fixCrypto on-ramp payment.completed webhooks fill in received_usd again. For payments that arrived as POL, PYUSD, or USDC outside Polygon, received_usd was sent as null and the payment was completed without our usual underpayment check. Both work as before now: received_usd carries the USD value of received_amount, and a payment that arrives well short of the order amount fails as underpayment.
September 29, 2026v3.31
  • improvedCustomers now return to your site from vexutopia.com. When a payment finishes on a partner payment page, the customer is sent back through vexutopia.com/pay/return/… to your return_url, instead of being sent there straight from the partner's page. Your return_url is no longer shared outside Vexutopia, and your analytics record vexutopia.com as the referrer. The {payment_id} and status placeholders work as before and carry the id you created; once the payment is settled, status reflects our final result.
  • improvedError texts are consistent. When a payment is refused before the customer reaches checkout, error.message and failure_reason now use our own short wording (for example "The payment processor could not create this payment. The customer can retry or use another payment method.") instead of passing a partner's raw error text through. Error codes are unchanged, so integrations that branch on the code need no change.
  • fixA few metadata keys are reserved for Vexutopia's own use (for example originalTransactionId). They are now ignored if you send them in metadata on POST /v1/payments, card mandate charges, or Telegram Stars payments, and they are hidden from everything you read back, including POST /v1/payments/lookup. Your own keys, payment_method included, are stored and returned exactly as before.
  • fixGET /v1/payments/:id always returns a checkout_url on vexutopia.com, or null if there is nothing left to open. It no longer falls back to a partner's hosted page address on older payments.
  • fixResellers: Cash App invoices for your sub-merchants now show your brand name in the customer's wallet instead of "Vexutopia".
  • improvedMonthly fee statements (Dashboard → Invoices) show the total fees you paid per payment method, the same figure as your dashboard and CSV export, instead of only part of it.
September 26, 2026v3.30
  • improvedClearer error when a payment method is in maintenance. A payment that could not be created only because the method that would have taken it is in maintenance now returns 503 PAYMENT_METHOD_MAINTENANCE, naming the method in a methods list and including our maintenance note — instead of 422 NO_PROVIDER_AVAILABLE, which read like a problem with your request. Retrying later can succeed. It is returned only when maintenance is the actual reason: if the method could not have taken the payment anyway, you still get NO_PROVIDER_AVAILABLE. The existing MASTERCARD_MAINTENANCE and CARD_DIRECT_MAINTENANCE codes are now in the errors reference too.
September 25, 2026v3.29
  • newYou can now limit which payment methods a customer can use for a payment. Pass allowed_methods on POST /v1/payments — for example ["gift_card"] behind a "Pay with gift card" button — and every other method is hidden from the checkout and refused if the customer tries to start it another way, so the customer can no longer switch to a different method than the one they chose on your site. Unlike preferred_method, local methods such as PIX or Alipay are hidden too. Available on USD hosted checkouts; omit it to keep offering every method. See the Payments docs for the accepted names. Whatever you use, payment.completed reports the method the customer actually paid with in payment_method — record that rather than the button they clicked.
September 24, 2026v3.28
  • fixFixed webhooks being rejected with 401 when a payment's webhook_url is the same URL as one of your registered webhook endpoints. The first delivery of some events (crypto and local bank payment status updates) and every automatic retry of any event were signed with the wrong secret, so your signature check correctly refused them — while the same event resent from the dashboard went through. All deliveries now use that endpoint's secret. If you saw payments with a missing payment.completed, use Resend on the Payments page to receive it now.
September 23, 2026v3.27
  • fixResending a webhook from the Payments page no longer fails with "Transaction not found" while a site is selected in the site switcher. The list and the Resend button were matching payments to sites in two different ways, so a payment shown under a site could not be resent from that view. Both now use the same site.
  • improvedPayment CSV exports now include the source site of each payment: the Payments page "Export CSV" adds SITE and SITE URL columns, and the Reports transaction export adds site and site_url. The site is the one your API key belongs to, or the registered site whose domain matches the payment's return_url; it is empty when neither applies.
September 23, 2026v3.26
  • fixThe site selector on your dashboard now works when you use a single API key for all your sites. Previously a payment was only linked to a site if it was created with that site's own API key, so filtering by site showed no payments at all for most accounts. Payments are now also linked to a site when their return_url is on one of your registered site domains (subdomains included) — and this has been applied to your past payments too. Payments created with a site-specific API key keep that site. This only affects reporting: which payment methods your customers see, and where your webhooks are sent, are unchanged.
September 23, 2026v3.25
  • fixThe gift-card docs no longer list $2.50 as a denomination you can pass. That face was retired on 19 September and the API already rejected it, but three places in the docs still advertised it. Denomination lists in the docs are now generated from the live catalogue.
  • newChoose which payment method your customers land on. Pass preferred_method on POST /v1/payments — card, card_direct, mastercard, cashapp, gift_card or telegram_stars — and that method is pre-selected on the hosted checkout and listed first. Nothing is hidden: every other method you have on stays one tap away. Send it per payment, so you can lead with one method for some customers and not others. Local methods still lead for customers in their own country (Alipay and WeChat in China; PIX, C2C, SBP, QRIS, GCash and Maya in theirs).
  • improvedThe Telegram Stars tile now sits with the other global methods in the checkout list instead of above the crypto on-ramp suppliers, matching the order the checkout already used when picking a default method.
September 22, 2026v3.24
  • newWordPress plugin (v1.1.0) — accept Vexutopia payments on any WordPress site with a pay-button shortcode and a WooCommerce gateway. It creates a payment, redirects the customer to the hosted checkout, and marks orders paid, failed, refunded, or cancelled from the webhooks. It supports the same checkout options as the API (crypto, Mastercard, card-only, regional methods, country, locale, and gift-card faces), pins pay-button amounts server-side, and sends an Idempotency-Key so a retry never creates a duplicate payment. Balances, payouts, fees, and analytics stay on the dashboard. Ask your account manager for the zip.
September 22, 2026v3.23
  • newcard_direct: true on POST /v1/payments sends the customer straight to the card page of a merchant who processes cards on their own acquirer account (vexutopia.com/pay/card-direct/…) — a dedicated "Pay by card" button next to crypto: true. payment_method: "card_fb_direct" is accepted as an alias; combine with save_card for renewals.
  • fixMerchants with card acquiring on their own account: a plain hosted-checkout session now always opens the multi-method page with Card first, instead of whichever rail automatic routing picked for the currency (a merchant without an on-ramp wallet was sent to a crypto invoice).
September 22, 2026v3.22
  • improvedCard acquiring on your own acquirer account now supports a second set of 3-D Secure credentials next to the default ones (Settings → Card acquirer). Cards from countries that require strong customer authentication (EEA, UK, Switzerland) are processed with the 3-D Secure credentials, everyone else with the default ones, and a payment the acquirer declines because it requires 3-D Secure is automatically re-opened with the 3-D Secure credentials — the customer is asked to enter the card once more, nothing is charged twice. Saved cards stay bound to the credentials they were saved with.
September 22, 2026v3.21
  • newSaved cards and renewals for merchants who process cards on their own acquirer account. Pass save_card: true on POST /v1/payments; once the customer pays by card, payment.completed and GET /v1/payments/{id} carry card_mandate ({ id, status, card: { last4, expiry, label }, currency, customer_id }). Charge it later without the customer with POST /v1/card-mandates/{id}/charge ({ amount, currency, reference }) — the answer is synchronous (completed / failed with failure_code and the issuer's advice code / pending), reference makes a charge idempotent, and the usual payment.completed / payment.failed webhooks fire. GET and DELETE /v1/card-mandates/{id} read and revoke a mandate. The card page tells the customer their card will be kept for renewals, in all 25 checkout languages.
September 22, 2026v3.20
  • newShow what the customer is buying on the hosted checkout. POST /v1/payments takes three new optional fields: description ("Yearly Subscription"), details ("2,000 initial coins, then 1,000 coins per month") and subscription ({ interval, interval_count, amount, currency }), which renders a renewal notice in the checkout language — "After 365 days, your subscription renews automatically and costs €113.99 every 365 days. You can cancel anytime." All three are display-only; nothing changes about how the payment is charged or settled.
September 22, 2026v3.19
  • fixGift card payments now return the customer to your return_url. When a gift card payment completed, the customer was shown our generic "Payment received" page with a "Return home" button instead of being sent back to you — even when you had passed a return_url, which we had stored correctly but were not reading on that page. Gift card payments now redirect to your return_url on completion, exactly like every other payment method, including the {payment_id}, {transaction_id} and {status} placeholders. Your webhooks were unaffected throughout.
September 22, 2026v3.18
  • fixGET /v1/payments/{id} now reports payment_method and processor from the method the customer actually paid with. When a customer switched methods on the hosted checkout, GET reported the original session's method (card) while the webhook reported the one that settled — the two now agree. settled_via is unchanged. Applies to past payments too, since the value is computed on read.
September 22, 2026v3.17
  • fixBalances & payouts showed maturing funds unlocking a day earlier than they actually do, if your timezone is behind UTC. A balance that unlocked on the 22nd was listed as the 21st, so checking on the date we gave you showed nothing available to withdraw. Settlement dates are now shown in UTC, which is how they are calculated.
  • improvedA balance that is still maturing now tells you the date it starts unlocking instead of "check back soon", and the per-date breakdown is unchanged — open it to see how much unlocks on each day. A rail with nothing matured yet has no Request payout button because there is nothing to withdraw yet, not because the option is missing.
  • new"Hide zero balances" on Balances & payouts collapses the rails you are not using, and your choice is remembered. A rail is only hidden when it holds nothing at all — a balance that is still maturing, on hold, or recovering chargeback fees stays on screen even when the withdrawable amount reads 0.00.
September 21, 2026v3.16
  • improvedMastercard fee details are now spelled out in the payments docs. Your customer pays a EUR 0.62 fixed card fee on top of every order — it is the card network's per-transaction fee, charged to the customer and kept by the network, so it never touches your payout. Your own fee on the rail is 19% per transaction (no payout fee, no refund fee, EUR 100 per chargeback), now listed in the same section.
  • newThe Webhooks docs now explain how to test your webhook handler. Create a payment with a test API key, open the test checkout, and click Simulate Success or Failure — a signed webhook fires to your webhook_url exactly as it will in production, marked livemode: false. You can also route test traffic to a dedicated mode: "test" endpoint, or re-fire a real completed webhook with POST /v1/payments/:id/resend-webhook.
September 21, 2026v3.15
  • fixCustomers are no longer blocked by other customers' failed payments. We limit how many payments one customer can fail in a day, but if you create payments from your own server, every one of your customers reached us from the same address — so that limit was being applied to your whole customer base at once, and a customer who had never failed anything could be turned away with "Too many payment attempts". The limit now applies per customer, and a customer is only linked to an address we saw them use themselves. Nothing changes for genuine repeat failures.
  • improvedWe now pass the customer's own IP address to the payment provider when we have it, instead of the address the payment was created from. If you create payments server-side, this previously made all of your customers look like a single device to the provider's risk checks, which could cost you approvals.
September 19, 2026v3.14
  • improvedPOST /v1/payments now accepts payment_method: "mastercard" (in any letter case) as an alias for mastercard: true, so a Mastercard checkout is one flag whether you use the boolean or the method field. EUR orders sent this way now open the Mastercard checkout instead of failing with NO_PROVIDER_AVAILABLE.
  • improvedRemoved the last references to the discontinued EUR bank-transfer method from the API and docs: it no longer appears as a payment_method value, in error messages, or among the regional methods you can switch off per site. A EUR payment without Mastercard now explains that EUR is taken by Mastercard only. Past transactions made with it are unchanged.
September 19, 2026v3.13
  • newWhitelabel resellers can now set their own checkout branding. A new Brand page in your reseller dashboard lets you set the brand name, logo, accent colour, favicon and support email that your sub-merchants' customers see in place of the platform name. Every field is optional, current values are shown for editing, and saves take effect immediately. Your merchants keep their own name and logo on checkout — this only replaces the platform branding, so leave the brand name blank if you'd rather show no platform name at all.
September 19, 2026v3.12
  • fixUSD payments created without a payment method no longer fail with NO_PROVIDER_AVAILABLE when Mastercard could take them. If you are approved for Mastercard and show it on your main checkout, we now open your full hosted checkout — with Mastercard and your other enabled methods — instead of returning an error. Previously this only happened when the amount matched a gift card denomination.
  • improvedThe Mastercard docs now list the countries where Mastercard is not available: Afghanistan, Albania, Barbados, Burkina Faso, Cambodia, Cayman Islands, Cuba, Haiti, Jamaica, Jordan, Mali, Malta, Morocco, Myanmar, Nicaragua, North Korea, Pakistan, Panama, Philippines, Senegal, Somalia, South Sudan, Syria, Uganda, Venezuela and Yemen. Pass the customer's country and these return 422 COUNTRY_NOT_SUPPORTED up front. COUNTRY_NOT_SUPPORTED, AMOUNT_BELOW_MINIMUM and AMOUNT_ABOVE_MAXIMUM are now in the errors reference.
  • improvedThe $2.50 gift card denomination has been retired. The smallest face is now $5, covering invoices from $4.50 to $5.00. Passing gift_card_amount: 2.5 is no longer accepted, and the denominations table in the docs has been updated to match.
September 18, 2026v3.11
  • newChargeback fees are now listed per payment method. The fee summary on the Payment Providers docs page has a Chargeback column covering every rail, including the ones that never had a figure published — crypto in and out have no chargeback mechanism at all, so they show a dash rather than a fee.
  • newMastercard is now open to request. It is listed in the fee summary on the Payment Providers docs page, and you can ask for it per site under Settings → Payment Methods. We review the site and enable it — no other rail needs this, and nothing else about your account changes while you wait.
  • newMastercard: choose where it appears. Once a site is approved, Settings → Payment Methods gets a "Show Mastercard on your main checkout" switch. Leave it on to list Mastercard alongside your other payment methods; switch it off to keep it to its own button — mastercard: true on POST /v1/payments still opens a Mastercard-only checkout either way.
  • improvedMastercard fee schedule updated: 19% per transaction, no payout fee, no refund fee, EUR 100 per chargeback, EUR 2 minimum per order, settling T+3. Your fee schedule in the dashboard always shows the rate in force.
  • improvedDashboard method tiles and charts no longer list Open Banking, which is discontinued. Mastercard now appears there once your site is approved and the method is on; historical volume for either stays in your transaction list.
  • improvedThe errors reference now documents MASTERCARD_NOT_ENABLED and MASTERCARD_DISABLED, and the Mastercard section of the payments docs spells out both account switches — the method itself, and whether it is offered on your main checkout. Both errors are 403; the docs previously said 422.
  • improvedTransaction exports now carry a single fee column per currency basis — fee and fee_usd — instead of splitting each into two. What you paid and what you netted are unchanged; if you parse the CSV by column name, update it for the new headers.
September 18, 2026v3.10
  • improvedClearer error when an Indonesian QRIS payment is missing the customer's mobile number. The message now explains that the QR payment page cannot be generated without it — it is not a location check — and points to the alternative: create the payment in USD instead and the hosted checkout asks the customer for the number, so you never have to collect or store it. The same note is on the CUSTOMER_PHONE_REQUIRED row in the errors reference.
September 18, 2026v3.09
  • improvedSupport can now send you images too. Replies in Help & support can include screenshots — useful when it's quicker to show you where something is than to describe it. The same limits apply as for your own attachments.
September 18, 2026v3.08
  • newYou can attach screenshots to a support message. Up to 3 images per message, 5MB each, in PNG, JPEG, WebP or GIF — a picture of the error usually saves a round of questions. Images are processed on upload, which also removes any camera or location data your device may have embedded in them. Other file types, including PDFs, are not accepted for now.
September 17, 2026v3.07
  • newHelp & support is now in your dashboard. Message us about a payment, a payout, fees or your integration from the new Help & support page in the sidebar, and read our replies in the same place — no email needed. A dot appears next to Help & support whenever we have answered and you haven't opened the conversation yet. Replying to a conversation we closed reopens it, so you can follow up on the same thread instead of starting over.
September 17, 2026v3.06
  • fixRemoved phantom "Cancelled" payments from your dashboard. When a customer starts checkout and then pays with Alipay, WeChat Pay, Indonesia QRIS, Philippines GCash / Maya, or Mastercard, the original checkout session is closed internally and should never be shown to you — but for these methods it was appearing as a separate cancelled payment next to the real completed one. Those rows are now hidden from Transactions, Customers, the Overview stats and CSV exports, and they no longer lower your success rate. Your completed payments, balances and payouts are unchanged.
September 17, 2026v3.05
  • improvedMastercard checkout errors are clearer. When the card form can't be opened, the customer now sees a specific message instead of a generic "Failed to start card payment", and an email address that was not accepted is no longer kept on the payment page — so a customer who retries can enter a different one instead of being stuck with it.
September 17, 2026v3.04
  • fixMastercard, Indonesia QRIS, and Philippines GCash / Maya earnings now show on your Balances page and can be withdrawn. Payments on these methods were completed and your webhooks were sent, but their balances were left out of the Balances page, so the money never appeared as withdrawable. Nothing was lost: every past payment on these methods is now counted, on its normal settlement schedule (Mastercard settles in 3 days, QRIS / GCash / Maya the same day).
  • improvedMastercard checkout confirms payments faster and returns the customer to your site automatically. After the card is submitted, the page no longer offers "Try again" or "Return to merchant" while the bank is still confirming — both could lead a customer who had already paid to pay twice or be sent back as cancelled. It now keeps confirming and redirects on the final result.
September 16, 2026v3.03
  • newMastercard is available for selected accounts as its own entry point, like Telegram Stars or crypto: pass mastercard: true on POST /v1/payments to send customers straight to the Mastercard checkout from a dedicated button. It does not appear on the multi-method hosted checkout. 16.7% per transaction, charged in EUR, EUR 2 minimum per order with a ceiling around EUR 500 that moves with exchange rates. Settles T+3, no rolling reserve and no payout fee. $50 per chargeback. Your customer pays a EUR 0.62 card fee on top of the order total. Not offered in every country. Off until we enable it for your account.
September 16, 2026v3.02
  • improvedCash App now requires both the customer's region and their connection to be US, not just their connection. A customer on a US IP who has selected a non-US region no longer sees the Cash App tile, and a forced checkout is refused. This keeps Cash App to genuine US customers and reduces mismatched attempts. Test-mode checkouts still skip the geo check.
September 14, 2026v3.01
  • improvedCash App is on for every merchant. US customers see it on hosted checkout ($3 minimum). Hide it from Settings if you do not want it.
September 14, 2026v3.00
  • newCash App is on hosted checkout for US customers. They pay a Lightning invoice from the Cash App app — this is not Cash App Pay and not a Bitcoin address. You are credited the invoice in USD at 7%. Same-day settlement, weekly payouts. $3 minimum. New York Cash App accounts may not be able to pay. Off until we enable it for your account; you can then hide it from Settings.
  • improvedThe Cash App tile on hosted checkout now uses the Cash App logo. The subtitle says to pay in the Cash App app, and notes that New York may not work — it no longer mentions Lightning.
  • fixCash App checkout now shows the payment request in readable text with a copy button. The old "other Lightning wallet" control hid the invoice, and the nearby test-mode button looked like an empty address field — tapping it marked a test payment paid and sent the customer to the success page.
  • improvedOn US hosted checkout, Cash App is selected first and listed above Gift Card. PIX, cards, and other regional rails are unchanged.
September 12, 2026v2.99
  • improvedGift Card payouts are now T+1. You can request one Gift Card withdrawal per day — the weekly 7-day wait no longer applies. PIX and other rails are unchanged.
September 8, 2026v2.98
  • fixA withdrawal could sit in Processing indefinitely behind a transaction that never reached the blockchain. Those sends are now detected and retried, and a withdrawal that can't be sent automatically goes to manual settlement instead of stalling.
September 8, 2026v2.97
  • fixWithdraw all now names each balance the same way the cards do — Gift Card shows as Gift Card, not a raw USD code.
September 7, 2026v2.96
  • fixRequesting a crypto payout no longer counts as your Gift Card payout for the weekly cooldown. If you have both balances, you can withdraw each rail on its own schedule.
  • fixA single crypto transaction that paid two invoices (two deposit addresses in one send) could credit only the first. Both now complete.
September 5, 2026v2.95
  • improvedOpen Banking (EUR bank transfers) has been discontinued and is no longer available for new payments. It has been removed from the checkout, your dashboard payment-method settings, the Fee Schedule, and the API — new EUR transactions on this rail are declined. Your existing Open Banking balances, payouts, transaction history, and settlement holds are unaffected and continue to work exactly as before.
September 2, 2026v2.94
  • fixTelegram Stars balance now matches your Transactions tab. Stars fees are volume-tiered (5/4/3/2%) and each payment is charged at the tier in force when it was made — that is what Transactions shows. The withdrawable balance, however, was repricing your entire Stars history at your current tier every time you crossed a threshold, so it drifted above the fees you were actually invoiced. It now credits every payment at its own invoiced rate. If you recently crossed a tier you may see the Stars available figure step down to the invoiced total; nothing already paid out is affected.
  • fixChargeback fees settled out of a payout now leave your balance. When a payout netted an outstanding chargeback fee, the fee was taken from the amount sent but the balance engine only debited the amount you received — so the fee reappeared as withdrawable on your next request. The deduction is now recorded in the payout currency and debited alongside the payout. Payout details continue to show the fee as its own line.
  • fixGift Card balances no longer carry the 1.5% Card Payments settlement fee. The fee belongs to the Card Payments rail and was being applied to any USD bucket, including USD Gift Card earnings. Anything already withheld on a Gift Card payout is back in that balance.
September 2, 2026v2.93
  • fixLive crypto payment.completed (and payment.processing / payment.partial) webhooks now include the metadata you sent on POST /v1/payments — same as the test-mode simulator. Previously the live crypto callback omitted metadata, so a field like metadata.order_id was missing in production. Top-level id / payment_id / order_id are unchanged (they remain our payment session id).
August 30, 2026v2.92
  • newPOST /v1/payments/telegram-stars accepts currency "XTR" with a whole-star amount, so you can charge an exact pack (e.g. 1500 stars). The customer pays that integer; USD is derived only for fees and the dashboard. Existing USD requests are unchanged and still ceil-convert to stars.
August 30, 2026v2.91
  • fixThe small-order card-to-crypto on-ramp option US customers already had is now also offered to EU/EEA/UK customers. A sub-$6 European order previously hid that option unless the customer switched the region picker to United States — and that handoff could fail to load the payment page. The on-ramp redirect also no longer forwards our checkout language parameter.
August 28, 2026v2.90
  • improvedGift Card is 16% + $1 per invoice (was 16% + $1.16).
August 26, 2026v2.89
  • improvedGift Card chat puts “Try another store” next to “I got my code” so it is not cut off at the end of the chip row.
August 26, 2026v2.88
  • improvedGift Card is 16% + $1.16 per invoice. The $1 face is gone — the smallest card is $2.50.
August 26, 2026v2.87
  • improvedGift Card is now 15.9% + $1.16 per invoice (was 10%). Settles T+0 after the code redeems; you are still credited the invoice, not the card face.
August 26, 2026v2.86
  • fixIndonesian QRIS via the API now requires customer_phone. Requests without a valid Indonesian mobile return 422 CUSTOMER_PHONE_REQUIRED instead of creating an incomplete order. 08… and +62… are accepted and stored as 628….
August 25, 2026v2.85
  • newHosted checkout and Gift Card chat now have a language picker. Customers can switch among the 25 supported languages; the choice is kept for the rest of that payment.
August 25, 2026v2.84
  • improvedThe Gift Card mark on the Pay via bar and on dashboard/admin lists is now closer to the size used in the checkout method picker.
August 25, 2026v2.83
  • improvedGift Card’s card-and-ribbon mark is sized to match the other method icons in admin and dashboard lists. Telegram Stars now uses the Telegram paper-plane logo instead of a gold star.
August 25, 2026v2.82
  • improvedGift Card now uses a yellow card-and-ribbon mark on hosted checkout, the dashboard, and admin lists. The ticket and wrapped-gift emojis are gone.
August 24, 2026v2.81
  • fixCrypto on-ramp payments that expire before settlement can still complete when a late payment confirmation arrives. Merchants may receive payment.completed after payment.expired — treat completed as authoritative. A retry that already completed under the same order_id will not revive the expired session.
August 24, 2026v2.80
  • improvedDirect card acquiring is not offered. It is gone from dashboard method cards, settings, balances, and checkout. POST /v1/payments with card_payment:true returns NO_PROVIDER_AVAILABLE.
August 24, 2026v2.79
  • fixDANA no longer appears on dashboard method cards. Indonesia is QRIS only.
August 24, 2026v2.78
  • improvedDirect card acquiring is not offered. Payments docs no longer describe a Card Payments rail, card_payment flag, or embedded card checkout. Use hosted checkout with crypto on-ramp, regional methods, gift cards, or crypto.
August 24, 2026v2.77
  • improvedIndonesia is QRIS only. DANA is not offered.
August 24, 2026v2.76
  • fixCreating a USD payment with Gift Card no longer fails when Crypto On-Ramp and cards are off. If Gift Card is enabled and the invoice fits a face, POST /v1/payments returns a hosted checkout instead of NO_PROVIDER_AVAILABLE.
August 24, 2026v2.75
  • newPayments docs now cover Indonesia QRIS and Philippines GCash / Maya: create an IDR or PHP payment, 10% all-in, same-day settlement, and the native limits.
August 24, 2026v2.74
  • improvedQRIS, GCash, and Maya are all 10%. DANA will be 10% too when it comes back.
August 24, 2026v2.73
  • improvedIndonesia QRIS is 9.5% and the Philippines is 9% on GCash / 10% on Maya — the live rates, not the 12% placeholder. Orders must be 10,000–10,000,000 IDR or 100–50,000 PHP. These rails now settle the same day (T+0). DANA is still unavailable.
August 24, 2026v2.72
  • improvedGift Card fee is 10% of the invoice. The 8% we had published understated the all-in merchant rate.
August 23, 2026v2.71
  • improvedGift Card checkout and chat now use the same 25 languages as the rest of hosted checkout. The tile, Support replies, and How-to sheet follow ?locale= the same way /pay does.
August 23, 2026v2.70
  • fixGift Card Open new checkout now opens the other store in its own tab. After you had already opened the first store, the new button was bringing that same first-store tab back instead of the new page.
August 23, 2026v2.69
  • improvedGift Card chat now puts an Open new checkout button in the message when we switch stores, instead of pasting a raw store URL.
August 23, 2026v2.67
  • improvedGift Card checkout keeps the Open checkout button. If we switch you to another store, that button becomes Open new checkout, the card says New link, and the chat says the old page is gone so you do not have to know store names.
August 23, 2026v2.65
  • improvedIf the gift-card store isn't working, Gift Card chat now says the checkout moved to an alternate store. The button at the top changes to open the alternate store, the card shows which store it is on, and the new store link is in the message so it is obvious you are not opening the old page.
August 23, 2026v2.64
  • fixGift Card chat quick replies on a phone no longer sit on top of the horizontal scrollbar. The bar now has a gap under the pills.
August 23, 2026v2.63
  • improvedAdmin merchant pages now show Gift Card (on by default, with a disable switch). The old card-acquirer approval block is gone from those pages and from Payment Method Maintenance.
August 23, 2026v2.62
  • fixGift Card chat no longer zoom-locks on iPhone after you tap the code box. Safari was magnifying the page because the field was smaller than 16px, and it stayed zoomed when the keyboard closed.
August 23, 2026v2.61
  • improvedGift Card is on for every merchant by default. No approval step. Hide the tile from Settings → Method enables if you do not want it.
August 23, 2026v2.59
  • improvedGift Card how-to now has left and right arrows on the screenshots on desktop, so you can move between steps without guessing that the photos swipe.
August 23, 2026v2.58
  • improvedGift Card chat now pins the store checkout and step tracker under Support, so Open checkout and Show me how stay put while you talk. After you open the store, a refresh still lands on the buy/paste step. The session stays open for 4 hours so there is time to finish the store purchase.
August 23, 2026v2.57
  • improvedGift Card checkout now has a Show me how walkthrough — five store screenshots with captions, swipe or Next on a phone, and the full photo in frame (not cropped).
August 23, 2026v2.56
  • improvedBitcoin, Litecoin, Monero, and other non-stablecoin invoices now stay payable for 45 minutes instead of 20. The old window expired for more than half of BTC payments before the chain confirmed them — we still credited those late, but the checkout timer already showed expired. USDT/USDC/DAI stay at 60 minutes.
August 23, 2026v2.55
  • improvedCrypto On-Ramp is available again as soon as a USDC payout wallet is set — no separate site approval. Existing merchants with a wallet already configured are included. Direct Crypto is unchanged and still needs approval.
August 23, 2026v2.54
  • improvedDashboard method cards now show Indonesia flags on QRIS and DANA, Philippines flags on GCash and Maya, and a gift-box mark on Gift Card — same lead-icon row as Alipay and WeChat Pay.
August 23, 2026v2.53
  • improvedGift Card fee is now 8% of the invoice (T+0). Dashboard fee schedule and docs match.
August 23, 2026v2.52
  • improvedGift Card docs now spell out the hosted checkout path (pin the face, customer pastes a 16-character code, payment.completed with payment_method gift_card), list gift_card on webhooks, and show the 15% row on the provider fee table.
August 23, 2026v2.51
  • improvedGift Card again includes $15 ($13.50–$15.00), so a $14 invoice can use the rail. The face-and-window table is now on the Payments API docs as well as the Gift Card page.
August 23, 2026v2.50
  • improvedIf the usual gift-card listing is sold out, checkout stays on that store and opens another in-stock listing for the same face. It only switches stores when every listing there is gone. Sold-out faces are rechecked daily.
August 23, 2026v2.49
  • fixThe gift-card alternate store now includes the $500 face.
August 23, 2026v2.48
  • fixThe gift-card alternate store now includes $1, $30, $40, and $75 — the same faces the default store already sold. If the default store is sold out on those amounts, checkout opens the other store instead of hiding the tile.
August 23, 2026v2.47
  • improvedIf the default gift-card store is sold out for the face on the invoice, checkout opens the other store when that same face is listed there. The gift-card tile stays hidden when neither store has that face in stock.
August 23, 2026v2.46
  • improvedGift Card denominations now match the store ladder: $1, $2.50, $5, $10, $20, $25, $30, $40, $50, $75, $100, $250, and $500. $15 was removed because that face is not sold on the default store. "Try another store" only appears when the same face is listed on both stores.
August 22, 2026v2.45
  • newGift Card checkout for approved merchants. Customers buy a USD gift card and paste the activation code. Faces are $5, $10, $15, $20, $25, $50, $100, $250, and $500. The invoice must sit in that face's window (90% of face up to face), so an $8 product cannot use a $5 or $10 card. Pass gift_card_amount on POST /v1/payments to choose the face shown. See the Gift Card docs.
August 20, 2026v2.44
  • improvedOne card-to-crypto option is no longer offered on the crypto on-ramp. It was withdrawn entirely — it is not hidden by a minimum order size, so it will not appear at any amount. Checkout still offers the remaining card-to-crypto on-ramp options, which vary by the customer's country and amount. On-ramp ranking now uses the invoice's USD equivalent, so a non-USD order is no longer compared against dollar minima as if the native figure were dollars. No merchant action needed; customers who used the withdrawn option can pick another on-ramp option shown at checkout for the same card-to-crypto flow.
  • fixAffiliate Earnings now matches the Transactions tab for the same commission. A $1.035 earning used to show as $1.03 on Transactions and $1.04 on Earnings, so a row could look missing when you searched by the Transactions figure. Earnings also only loaded the latest 50 rows with no way to go further — on a high-volume referred merchant the first page is almost all that merchant, and commissions from quieter merchants sink off the page. The list now shows a Ref that matches Transactions (TX-XXXXXX), a "showing X of Y" count, and Load more. Changing the merchant filter no longer reloads the whole affiliate dashboard, which could leave All merchants selected while the table still showed the previous merchant.
August 20, 2026v2.43
  • newNew local payment methods for Southeast Asia. Indonesian customers can now pay in IDR with QRIS or DANA, and customers in the Philippines can pay in PHP with GCash or Maya. Create a transaction in IDR or PHP via the API (pass payment_method to pick QRIS/DANA or GCash/Maya, and customer_phone for Indonesia), or let customers choose right on the hosted checkout — the pay page auto-detects the region and shows the local methods. Request approval for regional payments from your dashboard to enable them.
August 1, 2026v2.40
  • improvedThe chargeback fee on PIX, C2C, Alipay, WeChat Pay, and Telegram Stars refunds is now $50 per dispute, up from $40. This is reflected on your Fee Schedule, the provider docs, and the per-row Fee column on the Refunds & Chargebacks page, and is applied to new disputes on those rails going forward. Card Payments ($60), SBP ($150), and Open Banking (€100 ≈ $108) are unchanged.
July 29, 2026v2.39
  • fixRestored automatic recovery of China-based payments (WeChat Pay / Alipay) whose real-time confirmation is missed. Our background reconciler double-checks each pending China-pay order against the processor's records and settles any that were paid but didn't confirm in real time. Since July 28 that safety-net had silently stopped settling, so a paid order whose live confirmation dropped would sit unconfirmed until it expired. It works again, and missed confirmations are settled within minutes. Real-time confirmations were unaffected throughout; only the fallback recovery was impacted, and affected orders that the processor shows as paid are being reconciled.
July 28, 2026v2.38
  • newDogecoin (DOGE), XRP, and HYPE are now available as crypto payment options at checkout alongside BNB and your existing coins. Customers who choose one of these receive a deposit address (XRP also shows a destination tag) and pay the invoiced amount in that coin; after the network confirms, your merchant balance is credited in USD the same way as other crypto rails. No action is required to enable them if you already offer crypto — they appear when those networks are live on our side.
July 28, 2026v2.37
  • newMonero (XMR) is now available as a crypto payment option at checkout. Customers who choose Monero receive a unique deposit address and pay the invoiced amount in XMR; after the network confirms the payment (about 10 confirmations), your merchant balance is credited in USD the same way as other crypto rails. Monero carries a higher processing fee than stablecoin crypto (6% by default) because settling privacy-coin deposits into stablecoin has real market costs — your invoice USD amount is unchanged; only the fee line is different. No action is required to enable it if you already offer crypto — Monero appears alongside your existing coins.
July 25, 2026v2.36
  • fixAbandoned checkout sessions that were created without an expiry now reliably time out. A small number of payment sessions were generated with no expiry timestamp, so they stayed in "processing" indefinitely instead of ever resolving — never charged, never credited, but never closed either, which left them lingering on dashboards and in reporting. Any such session still open after a week is now automatically expired and, if you have a webhook configured, fires a payment.expired event like every other timed-out session. Sessions with a normal expiry window are unaffected, and a session that has actually received crypto funds is never expired.
July 24, 2026v2.35
  • fixCrypto payments on the remaining networks now confirm from more than one independent data source. Version 2.33 introduced multi-source confirmation, but some networks still read from a single source: if that source was unavailable or rate-limited, a payment could sit unconfirmed until its invoice expired even though the funds had already arrived, and would only be recovered by our end-of-life reconciliation afterwards. Those networks now fall back to reading the balance directly from the chain, so a data-source outage delays nothing. We also fixed a case where a rate-limited source returned an empty answer that was indistinguishable from "no payment received" — an incomplete answer is now treated as an error and retried elsewhere, instead of being read as an unpaid invoice. Payments that previously credited only after expiry now credit when they are made.
July 23, 2026v2.34
  • fixFixed the hosted checkout page and the embeddable checkout script briefly returning a "temporarily rate limited" error page instead of the payment options. On July 23, between roughly 16:00 and 16:55 UTC, a customer opening a checkout link on our checkout domain saw an error page rather than the method chooser, and the embedded widget failed to load for the same reason. The cause was on our side and not with any payment provider: a routing layer sits in front of that domain purely to serve one card-processing step, but it had been set to receive every request to the domain — page views, scripts, images and automated traffic alike — and used up its daily allowance. It now handles only the single path that actually needs it, so normal checkout traffic is served directly and can no longer exhaust it. Checkout links on our main domain were unaffected throughout, as were payments already completed and all webhooks. The one card step that still routes through that layer returns to normal when its daily allowance resets at midnight UTC; until then, customers reaching the checkout page can complete payment with any other method you have enabled.
July 23, 2026v2.33
  • fixCrypto payments are no longer accepted on a network we can't currently confirm. Between July 21 and 23, one of the blockchain data sources behind our crypto checkout stopped responding. Deposit addresses are generated locally, so checkout kept issuing them normally and customers who paid received no confirmation — their funds were safe on-chain the whole time, but the payment sat unconfirmed and no payment.completed webhook fired. Every affected payment has since been located on-chain and credited, and the corresponding webhooks have been delivered to the merchants involved. Going forward, each network's confirmation path is health-checked continuously: a coin whose network we cannot currently read is hidden from the customer's coin list instead of being offered, so a payment is never taken on a network we can't confirm. Coins on unaffected networks stay available throughout, and if every network were unavailable the checkout falls back to our alternate crypto route automatically.
  • improvedCrypto confirmations now run against multiple independent blockchain data sources per network. Each supported network is configured with a prioritised list of providers; if one starts failing or hits a capacity limit, confirmations move to the next automatically and stay there, with no interruption to payments in progress. Confirmation scans also adapt to each provider's own query limits rather than assuming a fixed one, which removes the class of failure where a provider change silently reduced how far back we could look.
July 17, 2026v2.32
  • fixFixed "Withdraw all balances" failing with "Too big: expected string to have <=8 characters". If your account held a Card Payments or Open Banking balance, submitting a withdrawal for all currencies at once was rejected outright with that message, and no payouts were created — the request never got past our validation check. This was a leftover from the change that split your balances into a separate bucket per payment method (v2.29): the batch withdrawal was still checking those buckets against the older, shorter naming format and refusing anything longer. Withdrawing a single currency at a time was unaffected and always worked. "Withdraw all" now accepts every bucket, and your per-currency minimums, settlement holds, and destination address rules are applied exactly as before.
July 16, 2026v2.31
  • improvedWebhooks now signal chargebacks and refunds on every rail — and tell them apart. The payment.refunded event fires for all payment methods (card, crypto, regional, Alipay/WeChat, and Telegram Stars), not just Telegram Stars, whenever a completed payment is reversed. It now carries a new type field: "chargeback" for an involuntary reversal (a cardholder dispute, an Alipay/WeChat refund, or a Telegram Stars refund) or "refund" for a voluntary refund. The payload keeps the same identifiers you already use (id / payment_id / order_id = your root session ID) plus amount, currency, and status, so you can match it to the original order exactly like payment.completed and automatically reverse the customer's credit. Chargebacks recorded manually by our team now fire the same event. The webhook docs have been corrected to reflect this.
July 8, 2026v2.30
  • fixCrypto payments are now reliably reconciled and credited. If the real-time confirmation from our crypto processor was ever missed (for example during a brief network blip), a genuinely-paid crypto invoice could stay stuck as "processing" on your dashboard and not fire a payment.completed webhook. A new background job now cross-checks any open crypto invoice against the processor's own records every few minutes and, for any it confirms as fully paid, completes the order and sends the webhook automatically — the same self-healing we already run for Telegram Stars. Confirmed crypto payments now credit within minutes even if the live confirmation drops.
July 7, 2026v2.29
  • improvedYour Balances & payouts page now shows a separate bucket for each payment method instead of merging methods that share a currency. Previously EUR Card Payments and EUR Open Banking appeared as a single balance labelled with just one of them, which made it look like a method was missing. Each now has its own balance, rolling reserve, maturity schedule, minimum, and withdraw button, matching how the rest of your dashboard already breaks figures down by method. China Pay (Alipay + WeChat Pay) stays combined as one bucket since it settles as a single rail. Your totals are unchanged; they're just itemised correctly now.
July 7, 2026v2.28
  • newReports & Exports now lets you filter the Transactions export by status. Pick any combination of statuses (Completed, Processing, Pending, Failed, Expired, Cancelled, Refunded, Partially refunded) before downloading — or use the "Completed only" shortcut — so you can keep expired and pending noise out of your accounting and reconciliation exports. Leaving all statuses selected exports everything, exactly as before.
  • improvedDocs — the Webhooks page callout no longer implies the top-level id field is unsafe to use. All three identifier fields (id, payment_id, order_id) have been identical since 2026-05-09 — each equals your root session ID from POST /v1/payments — so any of them is fine for order lookups. The heading previously said "never look up by id," which contradicted the text directly below it; it now reads that all three are the same value, with the pre-2026-05-09 behaviour still noted for anyone reprocessing old stored payloads.
July 5, 2026v2.27
  • improvedUSDT and USDC withdrawals can now settle automatically. When you withdraw stablecoins from your crypto balance and the funds are ready to send, it's signed and sent on-chain right away — no manual approval and no weekly cooldown; if it can't be settled instantly it goes to the normal review queue instead. Crypto withdrawals are currently limited to USDT and USDC. Your other payout methods are unchanged.
July 4, 2026v2.26
  • fixSign-in now tells you when you've hit the login attempt limit. After several rapid failed attempts the login form briefly limits further tries — but it was showing a generic "Something went wrong. Please try again." instead of explaining why, so it wasn't clear that simply waiting a few minutes would resolve it. The form now shows "Too many sign-in attempts. Please wait a few minutes and try again.", and continuing to retry while limited no longer extends the wait. Your account is never locked by this; it clears on its own.
July 3, 2026v2.25
  • improvedWebhook endpoint auto-disable is now much more conservative. An endpoint is only auto-disabled after repeated "URL not found" (404/410) responses AND no successful delivery in the previous 24 hours — so a short burst of 404s on event types your handler doesn't process (for example if you 404 payment.expired but return 200 to payment.completed) will no longer pause a live endpoint. If an endpoint ever is auto-disabled, an alert is now raised immediately so it's never silent. Best practice remains to acknowledge every event you're subscribed to with a 2xx response, even ones you ignore.
  • fixWhen the same URL is both saved as a registered webhook endpoint and passed as a per-payment webhook_url, notifications to it are now always signed with your registered endpoint's secret. Previously a fallback delivery on that URL could be signed with a different key, so your signature check would correctly reject it — producing failed-verification (401) retries. Delivery is now consistent and de-duplicated to a single correctly-signed call per event.
  • fixRegistering a second webhook endpoint for a URL you've already registered now reuses the existing signing secret instead of generating a new one. Because your server verifies a given URL with a single secret, two registrations on the same URL with different secrets previously meant a portion of deliveries always failed your signature check. Endpoints on the same URL now share one secret, so every delivery verifies.
July 2, 2026v2.24
  • fixWhitelabel sub-merchants can now create payments through the API. Because sub-merchants settle through their reseller, they don't set a payout wallet of their own — but the payment endpoint was still requiring one on the sub-merchant's own account and returning WALLET_NOT_CONFIGURED (HTTP 400). It now uses the reseller's configured payout wallet, so a sub-merchant can transact as soon as their reseller has set one.
July 1, 2026v2.23
  • improvedCard checkout is more forgiving of unreadable postal / ZIP codes. If a customer's entry can't be interpreted at all (for example they type only symbols or characters that don't map to a standard postal code), the checkout now fills a valid placeholder in the correct format for their country instead of failing the payment. Postal codes that are entered validly are always used exactly as provided — this only affects entries that would otherwise be rejected outright.
July 1, 2026v2.22
  • fixCard checkout now enforces a valid postal / ZIP code (1–10 characters), matching what the card network accepts. Previously the billing form allowed a longer entry that passed our checks but was then rejected by the card processor for exceeding the length limit, causing the payment to fail. The field is now capped and validated end-to-end, and any non-standard characters are cleaned automatically, so affected card payments go through.
June 30, 2026v2.21
  • fixTelegram Stars payments are now reliably reconciled and credited. In rare cases a paid Stars order could stay stuck as "processing" on your dashboard — and not fire a payment.completed webhook — if the real-time confirmation from Telegram was missed (for example during a brief deployment). Our background reconciler, which cross-checks every bot's Telegram Stars ledger and settles any payment the real-time confirmation missed, was only re-checking the oldest payments and silently stopped catching recent ones once volume grew. It now tracks its position per bot and always checks the newest transactions, so a confirmed Stars payment is credited within minutes even if the live confirmation drops. Affected past orders are being settled retroactively.
June 30, 2026v2.20
  • newYour crypto checkout is now multi-coin. Customers paying in cryptocurrency can pick the coin and network they want right on the payment page — stablecoins (USDT, USDC) across Tron, BNB Smart Chain, Polygon, Ethereum, Base, Arbitrum and Solana, plus Bitcoin and Litecoin, and the networks' own coins (ETH, BNB, POL). Choosing a coin instantly shows the exact amount to send, a fresh address with a QR code, a live countdown, and a status that flips to confirmed the moment the payment lands on-chain. The page is translated across all 25 checkout languages (with right-to-left support) and carries your brand. Previously a crypto invoice was locked to a single coin chosen up front.
June 28, 2026v2.19
  • improvedYour Balances page now explains held funds. When some of your payments are temporarily held while we await settlement from the processor, each affected balance shows an "On hold · pending settlement" line — the held amount, the date range the payments fall in, and a note that they'll be added to your withdrawable balance once cleared. Previously these funds were simply missing from your balance with no explanation, which made the available amount look lower than expected.
June 27, 2026v2.18
  • improvedTelegram Stars no longer requires a TON wallet on file. Previously you had to link a TON payout address before you could enable Stars or accept Stars payments. That requirement — and the TON wallet field in Settings — has been removed. Stars proceeds now settle to your balance and are withdrawn like any other coin or network: you choose the destination wallet (TON included, alongside every other supported network) when you request a withdrawal. Enabling Stars at checkout is now a single toggle.
June 21, 2026v2.17
  • improvedThe chargeback fee on SBP (Russia) is now $150 per dispute, up from the previous ~$64.50. This reflects the higher cost of handling disputes on this rail. The updated amount is shown on your Fee Schedule, the provider docs, and the per-row Fee column on the Refunds & Chargebacks page, and is applied to SBP disputes going forward. Other rails are unchanged.
June 17, 2026v2.16
  • improvedWhitelabel resellers: the per-merchant pricing screen is clearer. Each payment type now shows your all-in cost as a single bundled figure, you enter just your fee (the markup you add on top), and the screen shows what your merchant pays — your cost plus your fee — live as you type. No change to how any merchant is billed.
June 14, 2026v2.15
  • improvedAdded guidance to the Authentication docs for server-to-server integrations: send a descriptive User-Agent header (e.g. "YourCompany-Integration/1.0"). Some HTTP clients send a generic or empty User-Agent that our edge bot-protection can challenge or block (showing a Cloudflare challenge or Error 1010). That is driven by the User-Agent, not your IP — setting an app-specific User-Agent resolves it.
June 13, 2026v2.14
  • fixFixed checkout crashing to a "Something went wrong" screen for customers whose browser auto-translated the page. Chrome's "Translate this page" (and similar tools) rewrite the page's text, which conflicts with how the checkout updates itself and could crash it mid-payment — the card page was hit hardest. We now tell the browser not to auto-translate the checkout, which is safe because the checkout already renders in 25 languages on its own. Customers who saw the error and had to reload should no longer hit it.
June 11, 2026v2.13
  • fixRegional payment chargebacks (PIX, C2C, SBP, Open Banking) are now recorded correctly. When the processor reports a chargeback on a settled regional payment, the transaction now moves to refunded, a chargeback is logged against it (appearing on your Refunds & Chargebacks page with the per-rail fee), the rolling-reserve/risk handling kicks in, and you receive a payment.refunded webhook — the same treatment card and other rails already had. Previously this specific dispute status wasn't mapped and the event was effectively ignored. No change to non-disputed payments.
June 10, 2026v2.12
  • fixPayments created with card_payment:true now honor the language you pass. These sessions open the hosted card page directly, which previously only read the language from the URL — so a merchant-supplied "locale" was ignored and the card form fell back to English. The card page now uses the locale saved on the payment (the same source the rest of the checkout already used), so sending locale together with card_payment:true renders the whole card form — labels, placeholders, validation, and buttons — in that language, including right-to-left layout for Arabic and Hebrew.
June 9, 2026v2.11
  • improvedDocs corrected for US card payments. The Providers, Embed, and Payments pages previously said US billing was "hosted-checkout only", couldn't run in the embedded iframe, and that the inline card endpoint returned 400 US_REQUIRES_HOSTED. That hasn't been true since US billing was re-enabled on the inline card flow — US cards now work on the standard inline card page and inside the embedded iframe, the same as every other country. The only US-specific requirements are a billing state and that the customer is on a US IP address (plus the $10 minimum). The dedicated US hosted-session endpoint (/api/v1/checkout/{id}/card-hosted) still works but is now optional, not required. No behavior change — only the documentation was out of date.
June 8, 2026v2.10
  • newYour hosted checkout now speaks 25 languages. Pass an optional "locale" when you create a payment (for example "fr", "de", "ja", or "ar") and the checkout renders in that language end to end — order summary and amounts, payment options and instructions, the card payment form, help, and the success screen — including full right-to-left layout for Arabic and Hebrew. If you don't pass one, nothing changes: the checkout still follows the customer's region (Portuguese in Brazil, Russian in Russia, Spanish in Argentina, Chinese in China) and falls back to English everywhere else. Languages added on top of the existing five: French, German, Italian, Dutch, Polish, Turkish, Japanese, Korean, Hindi, Indonesian, Vietnamese, Thai, Ukrainian, Romanian, Czech, Swedish, Greek, Traditional Chinese, Arabic, and Hebrew.
June 5, 2026v2.09
  • fixThe rolling reserve is now correctly withheld from your withdrawable balance. The 10% reserve held against chargebacks was being shown on your Balances page but was not actually reducing the amount you could withdraw — so reserved funds were withdrawable. Your "Available to withdraw" now excludes the active reserve for each currency, and that amount returns to your balance automatically as each hold ages out at 180 days. This only affects rails that carry a reserve (Card Payments and Open Banking).
  • fixThe 1.5% Card Payments settlement fee is now applied consistently on every payout. It was being deducted when you used "Withdraw all" but not on a single per-currency payout request; both paths now deduct it, matching the published fee schedule.
June 5, 2026v2.08
  • fixFixed a false "this website URL is already in use by another merchant" error when adding a Telegram bot (or other shared-host) link as a site URL. The uniqueness check was comparing only the domain, so every t.me bot collided with every other one even though the bot name in the link is what identifies you. Links on shared hosts (t.me, telegram.me, wa.me, linktr.ee) now compare on the full handle, so distinct bots no longer clash — while a genuine duplicate of the exact same bot is still blocked.
June 5, 2026v2.07
  • improvedTelegram Stars now requires a per-site approval, in line with every other rail. Existing sites were automatically approved, so nothing changes for current merchants. New sites request approval for Telegram Stars the same way they do for the other methods; a configured TON payout wallet and the Telegram Stars toggle still apply underneath.
June 5, 2026v2.06
  • improvedCrypto and Crypto On-Ramp are now governed by a per-site approval, approved together as a pair — bringing them in line with the other rails (Card Payments, regional methods, Alipay/WeChat) that already require site approval. Every existing site was automatically approved as part of this change, so nothing changes for current merchants. New sites request approval for the crypto rails the same way they do for the others. The per-method on/off toggles and USDC wallet requirement still apply underneath.
June 4, 2026v2.05
  • fixThe chargeback fee shown on each row of the Refunds & Chargebacks page is now the exact amount charged for that dispute, recorded when the chargeback is logged — so it no longer shifts if the fee schedule changes later, and the per-row total always matches your outstanding "Chargeback fees owed" balance. As part of this we reconciled existing chargebacks: every recorded dispute is now billed at the current rate and reflected in your owed balance, including some earlier Alipay/WeChat disputes that had not previously been charged. Going forward each dispute's fee is locked in at the moment it's recorded.
June 3, 2026v2.04
  • fixChargeback fees are now actually deducted from your balance at payout time. Previously the per-dispute fee was shown on the Refunds & Chargebacks page and tracked as "Chargeback fees owed," but nothing collected it — the amount could grow indefinitely without ever reducing a payout. Now, every chargeback (card, PIX, C2C, SBP, Open Banking, Alipay, WeChat Pay, and Telegram Stars refunds) accrues the fee as a liability, and your next payout automatically settles it: the outstanding total is converted into the payout currency, deducted from the disbursed amount, and the balance owed goes down accordingly. The payout request screen now shows the pending deduction before you submit.
  • improvedChargeback fees increased on several rails. The dispute fee on PIX, C2C, Alipay, WeChat Pay, and Telegram Stars refunds is now $40 (up from $30). Card Payments ($60), SBP (5,000 RUB ≈ $64.50), and Open Banking (€100 ≈ $108) are unchanged. The updated amounts are reflected on your fee schedule, the provider docs, and the per-row fee column on the Refunds & Chargebacks page.
June 2, 2026v2.03
  • newWebhook endpoints can now be scoped to a single Site. If you run multiple apps under one organization (each its own Site), you can bind an endpoint to a specific Site so it only receives that Site's payment events — instead of every endpoint in the organization receiving every event. Set it with the new optional `site_id` field when creating an endpoint via the API (POST /v1/webhooks), or pick a Site in Dashboard → Webhooks. Endpoints left unscoped stay organization-wide exactly as before, so nothing changes for existing endpoints. This is the recommended way to isolate webhooks per app while keeping a separate signing secret per endpoint (previously, true isolation required separate organizations).
June 2, 2026v2.02
  • improvedThe hosted card checkout page no longer briefly flashes a "payment failed" screen for card payments that recover to success a few seconds later. The upstream processor occasionally reports a momentary failure on an authorization that then succeeds — your customer would previously see the failure card flicker before being redirected to success. The checkout now keeps showing the processing spinner during the short grace window we already hold these on, then resolves cleanly to success (if it recovers) or to the failure screen (if it's a genuine decline). Net effect: a smoother checkout for your customers on the small fraction of card payments that briefly stumble before completing.
June 2, 2026v2.01
  • fixThe `payment.failed` webhook we send when a payment session can't be initialised now includes `payment_id` and `order_id` (both equal to the payment id we returned from POST /v1/payments), matching every other webhook we send. Previously this specific failure event carried only the `id` field, so integrations that correlate incoming webhooks by `payment_id`/`order_id` saw them as missing and could reject the event as an unknown order. No change to any other event or to successful/normal failure webhooks.
June 2, 2026v2.00
  • improvedHardened how we acknowledge incoming payment notifications from our processors so we stop losing them. Previously, when a processor notified us that a payment had completed, our endpoint tried to deliver your webhook (and run settlement bookkeeping) before acknowledging the processor — so if your endpoint was momentarily slow, the processor's call to us could time out, it would treat its notification as failed, and the payment could end up stuck as expired even though it succeeded (which sometimes led customers to retry and pay twice). We now acknowledge the processor immediately and deliver your webhook from a separate queue. The practical effect for you: payment webhooks now arrive within about a minute of the event rather than instantly, but they're far more reliable and no longer depend on your endpoint responding within the processor's timeout. Delivery, retries (5 attempts with backoff), signatures, and payload shape are all unchanged.
June 1, 2026v1.99
  • fixCard payments no longer send a transient `payment.failed` that is immediately contradicted by `payment.completed`. On the card rail, the upstream processor occasionally reports a momentary failure for an authorization that then succeeds a few seconds later — which previously fired a `payment.failed` webhook followed seconds later by `payment.completed` for the same order, so merchants saw a scary "order failed" for an order that actually went through. We now hold card `payment.failed` webhooks for a short grace window (about 60 seconds) and cancel them entirely if the payment completes in the meantime. Genuine card declines still notify you — just up to ~60 seconds later than before — so if your integration treats a failure as final the instant it arrives, you'll now get a cleaner, non-contradictory signal. Other rails and successful payments are unaffected and fire immediately as before.
June 1, 2026v1.98
  • fixCorrected a card failure code that was over-applied. During a card-network acquirer outage earlier in May we introduced a `card_brand_outage` code for one specific upstream error string, and excluded those from your success-rate metrics since they weren't real declines. That string turned out to be the acquirer's generic wording for a much broader set of outcomes, so after the outage cleared it was still being applied to ordinary card declines — which both mislabeled them as "not your fault" and wrongly excluded them from your success-rate denominator. Going forward, that upstream condition is classified as `provider_error` (our standard code for an unspecified upstream failure) and counts toward success rate like any other decline. The `card_brand_outage` code itself is retained for genuinely identified future brand outages. Historical transactions are unchanged, so you may see your card success rate step down slightly from this point forward as these failures are counted correctly — your actual approval behavior hasn't changed.
June 1, 2026v1.97
  • newYou can now set a separate "Checkout display name" in Settings → Organization. This is the name customers see at the top of the hosted checkout and card payment page (the "Paying …" line). Set it to a recognizable trading or brand name if you'd rather not show your legal entity name there — your organization name is still used for admin, invoices, and compliance. Leave it blank to keep showing your organization name. Note that the descriptor on the customer's bank statement is set by the card acquirer and is separate from this. The card payment page previously always used the legal organization name; it now respects this setting like the other checkout surfaces do.
May 31, 2026v1.96
  • fixFixed a case where a refunded Telegram Stars payment could revert to showing "Completed" on your transactions list. Telegram occasionally redelivers the original payment notification — sometimes days later — and a stale redelivery arriving after a refund was overwriting the refunded status back to completed (and re-counting the sale in your pending Stars balance). Stars payment notifications are now ignored once a transaction has reached a final state, so a refund stays a refund. One affected transaction was corrected.
  • improvedTelegram Stars customers now show an identifier on the transactions and Refunds & Chargebacks lists instead of just "anonymous". Telegram doesn't share an email or name for Stars buyers, so we now surface the Telegram charge id (shown as "TG·…" with the full id on hover) — a stable per-payment reference you can use to identify or reconcile the transaction.
May 31, 2026v1.95
  • fixFixed an intermittent HTTP 500 at checkout creation that could affect any rail when a request used an Idempotency-Key. Our idempotency store (which lets you safely retry a create with the same key) talks to a Redis backend, and if that backend was briefly unavailable the lookup raised an uncaught error that surfaced as a 500 — even though the payment itself was fine. The store now fails open exactly like our rate limiter: if Redis is unreachable, idempotency protection is skipped for that request and the create proceeds normally, rather than erroring. Requests without an Idempotency-Key were never affected. During such a Redis blip the only downside is that a genuine retry with the same key isn't deduplicated server-side, so send a fresh key per distinct order as you normally would.
May 31, 2026v1.94
  • fixFixed an intermittent HTTP 500 on the crypto on-ramp when a customer's browser fired the deposit-address request twice in quick succession (a double-click or an automatic client retry). Both requests could pass the initial check before either had finished, then race to attach the upstream session to the same payment — the second one failed a database uniqueness check and surfaced as a 500. The endpoint is now idempotent under this race: the second request returns the same deposit address the first one created instead of erroring. No change to the happy path, and no impact on funds — affected customers simply saw an error screen and had to retry; the underlying payment session was always fine.
May 31, 2026v1.93
  • improvedHardened the payout request flow with stricter validation and atomic processing. Requesting a payout now checks the destination address against the asset you've selected up front, and each request is recorded in a single atomic step so the payout pipeline stays consistent. Routine payout requests are unaffected — you may just see a clearer error if a request is malformed.
May 29, 2026v1.92
  • improvedVisa cards are accepted again on Card Payments. The temporary card-brand block — added while the upstream card acquirer worked through a Visa-side authorisation outage (2026-05-15 to 2026-05-20) — has been lifted now that the acquirer has confirmed Visa is back online. Customers paying by card no longer see the "Visa cards are temporarily unavailable" notice on the Card Payments tile, the hosted card form, or as an inline block when entering a Visa card number; Visa attempts route to the acquirer normally. Mastercard and every other rail were unaffected throughout and are unchanged. No merchant action needed.
May 29, 2026v1.91
  • improvedThe Balances card now shows the full maturity release schedule instead of a single date. When funds mature on a delay (Telegram Stars at T+21, Card Payments at T+7) and were earned across several days, the "Maturing" line now shows the date range (e.g. "09 Jun → 18 Jun") and is expandable — click it to reveal a per-day breakdown of exactly how much unlocks on each date. Collapsed by default so a long schedule stays tidy. Previously it showed only the earliest date next to the full maturing total, which made it look like the whole balance released at once.
May 28, 2026v1.90
  • fixDirect crypto earnings are now withdrawable on their own, separate from Card Payments. Crypto payments are priced in USD, so they used to share the same USD balance as Card Payments — which carries a $5,000 minimum payout for card-settlement reasons. That meant a merchant with, say, $60 of crypto couldn't withdraw it until the combined USD balance crossed $5,000. The Balances page now shows a dedicated "USD · Crypto" card with the standard $25 minimum and no settlement-window hold, so crypto can be paid out as soon as it's confirmed. The Card Payments USD card is unchanged ($5,000 minimum, T+7, 10% reserve). Crypto on-ramp is unaffected — it still settles straight to your wallet and was never held here. "Withdraw all" treats the two as independent buckets.
May 28, 2026v1.89
  • fixClarified the "Maturing" line on the Balances card. When a rail matures on a delay (e.g. Telegram Stars at T+21), funds earned across several days release across just as many dates — but the card showed the single earliest date with the full maturing total next to it, which read as though the entire balance unlocked on that one day. The line now says "first batch" instead of "next" so it's clear that date is the earliest of several rolling release dates, not the date the whole balance becomes withdrawable. Display-only change; maturity itself was always calculated per-transaction.
May 27, 2026v1.88
  • fixTelegram Stars now matures on a T+21 schedule on the merchant balance card, matching Telegram's 21-day customer-refund window. Previously we marked completed Stars sales as immediately matured (T+0) and showed Telegram's 21-day lock as a separate "Pending Stars" card below — but the two cards were two views of overlapping balances, which led merchants to add them together and assume their lifetime Stars revenue was roughly the sum of both. The "Available to withdraw" Stars number now reflects only Stars from sales whose 21-day refund window has closed, so what you see in the top card is genuinely what's safe to pay out. The duplicate "Pending Stars" card is removed for the positive case (it was double-counting the same Stars); the negative case (refunds exceeded Stars revenue, meaning your account owes Stars to the platform) is preserved with clearer copy. Stars earned within the last 21 days now appear in the existing "Maturing" sub-line of the Stars balance card. No data was changed — only the maturity rule on the balance computation and the dashboard layout. If you were about to request a Stars payout for Stars that just rolled to "Available" under the old rule, you'll now need to wait until each individual sale ages past 21 days; this matches the actual refund risk you carry on Telegram's side.
May 24, 2026v1.87
  • fix`payment.expired` webhooks are now fired when a checkout session times out without the customer paying. Previously the expiry sweep flipped the database row to `expired` in bulk but never notified your endpoint — merchants whose UI depended on a terminal webhook stayed stuck on "Payment Processing" indefinitely, only resolving once the customer manually returned to the merchant page (and even then only via the redirect URL, never via a webhook). The sweep now selects each expiring session individually, transitions it, and delivers a `payment.expired` event with the standard payload shape (`id`/`payment_id`/`order_id` aliased to your root session id, plus `failure_code: "invoice_expired"` and `failure_reason: "Session expired"`). Failed deliveries are retried by the existing webhook retry cron. No action required on your side if you already handle `payment.expired` — if you don't, this is the trigger to add it alongside `payment.failed` in your handler. Up to 200 sessions per minute are processed; the next tick picks up any backlog.
May 23, 2026v1.86
  • fixCrypto on-ramp sessions created through the on-the-fly path (introduced in v1.80, when a customer picks an on-ramp supplier on the checkout page after the session was routed to another rail first) were being created without the per-session reference our payment confirmation relies on, so a deposit could not be matched to its session — deposits went uncredited and sessions expired even when the customer's funds had landed. These sessions are now created the same way as direct `/v1/payments` calls, so their payments are matched and credited normally. Pre-existing sessions stuck in this state may still need manual reconciliation — flag any specific session you want unblocked.
May 23, 2026v1.85
  • fixCrypto on-ramp transactions created via the on-the-fly path added in v1.80 (customer picks an on-ramp supplier on the checkout page after the session was originally routed to another rail) were being tagged as Card Payments on the dashboard instead of Crypto On-Ramp. The deposit address and end-customer flow were correct; only the category tag and fee rate on the parent transaction were stale. These sessions are now tagged and priced on the on-ramp schedule. 172 historical rows from since v1.80 deployed have been corrected — they now show under Crypto On-Ramp in your dashboard.
May 23, 2026v1.84
  • improvedProvider docs now spell out the chargeback fee for every rail in a single place. Added the $30 Telegram Stars refund fee to the Telegram Stars section on the Providers page (it was already in the Telegram Stars docs and on your Fee Schedule, just missing here). The SBP and Open Banking rail cards now also show the USD equivalent next to the native-currency fee (RUB 5,000 ≈ $64.50, EUR 100 ≈ $108, EUR 3 refund ≈ $3.25), so the number you see in the docs matches the figure that lands on your Refunds & Chargebacks page when a dispute happens.
May 23, 2026v1.83
  • improvedTelegram Stars refunds are now logged the same way disputes on every other rail are. When Telegram Support refunds a Stars payment on a customer's behalf, the refund shows up on the Refunds & Chargebacks page (it previously only updated the transaction status — there was no row in the chargebacks list to look at). The per-refund operational fee is now $30 per refund (previously $10) and applies on Telegram Stars at the same rate as PIX, C2C, Alipay, and WeChat Pay. Refunded stars plus the $30 equivalent in stars are deducted from your pending Stars balance, and the $30 USD fee is reflected in the Fee column on the chargebacks table — same behaviour as the other rails. Two existing Telegram Stars refunds have been backfilled into the chargebacks list and re-priced at the new rate.
May 23, 2026v1.82
  • improvedRefunds & Chargebacks page now shows the chargeback fee charged on each disputed transaction. A new Fee column on the chargebacks table and a Chargeback fees (USD) summary card make it visible at a glance how much each dispute is costing you. Fees are surfaced from the published per-rail schedule — $60 on Card Payments, $30 on PIX / C2C / Alipay / WeChat Pay, around $64.50 on SBP, around $108 on Open Banking. Alipay and WeChat Pay disputes now carry a $30 operational fee per disputed transaction (previously listed as no chargeback fee). Customers can request a refund through their Alipay or WeChat app and that lands on our side as a dispute; the new fee covers the cost of handling it.
May 23, 2026v1.81
  • fixFollow-up to v1.80: the crypto on-ramp redirect was building the destination URL incorrectly and returned a 404 page when the customer clicked through. The redirect now goes to the correct on-ramp checkout page, so picking an on-ramp option on the checkout page correctly hands the customer off to the on-ramp flow. No integration changes needed.
May 23, 2026v1.80
  • fixCustomers who picked a crypto on-ramp supplier on the checkout page after we had routed their session to a different rail (typically Card Payments) used to see "Payment session data is incomplete. Please contact the merchant." — that was a stale-state bug, not a real session problem. The deposit address for the crypto on-ramp is now created on demand the moment the customer clicks an on-ramp supplier tile, so any session can switch to the on-ramp from the chooser as long as the merchant has a USDC wallet configured and the crypto on-ramp enabled. No integration changes needed on the merchant side.
May 22, 2026v1.79
  • improvedAlipay and WeChat Pay (CNY) balances are now payable daily instead of weekly, with a $100 USD minimum per request. Both rails settle T+1 and have no chargeback or refund window, so there's no reason to make merchants sit on the cash for a week — the new cadence lets China-pay-heavy merchants pull funds out as fast as they come in. The 7-day cooldown is unchanged on every other rail (Card Payments, PIX, C2C, SBP, Open Banking, Crypto, Telegram Stars). The per-rail rule is enforced independently, so a daily Alipay payout request does not affect your weekly cooldown for the other rails.
May 22, 2026v1.78
  • fixRefunds & Chargebacks page now loads correctly for high-volume merchants. The previous implementation pre-fetched every transaction ID for the organization and inlined them into the refunds query, which silently failed once an org crossed ~32k lifetime transactions (PostgreSQL's prepared-statement parameter cap). When that query failed the page fell back to an empty state, so affected merchants saw "Chargebacks (0)" even though chargebacks were recorded and visible on our internal side. Rewritten as a single SQL JOIN, no per-transaction parameter explosion, and the pre-flight transaction scan is gone — the page also loads noticeably faster on large accounts.
May 21, 2026v1.77
  • improvedCustomers who pick Card Payments on the checkout page now see a heads-up notice that Visa is temporarily unavailable — both under the Card Payments tile on /pay and at the top of the hosted card form. Previously the customer only found out after entering their Visa card number and hitting the inline form-level block (added in v1.72). The notice is in all 5 checkout languages (EN/PT-BR/ES/RU/ZH-CN), and clears automatically when Visa is re-enabled — same single source of truth as the form-level block and the server-side reject. Mastercard payments and every other rail are unaffected.
May 21, 2026v1.76
  • improvedFailure reasons on the Payments table are now a short red label (e.g. "Risk decline", "Card expired", "3DS failed", "Below minimum") with the full explanation in the hover tooltip — instead of a truncated error message that often didn't survive truncation. The same labels are mirrored on the `failure_code` field of `payment.failed` webhooks. Four new stable codes were added: `card_expired` (issuer reports the card expiry has passed), `customer_blocked` (the acquirer's risk system has flagged the customer's profile — a fresh card from the same person won't help), `amount_below_minimum` (the request is below the rail's per-order floor), and `merchant_integration_error` (the API call your integration sent was missing or had invalid fields). Existing codes are unchanged in meaning — `provider_error` is still the safe default for unknown values. Four classification bugs were fixed in the same pass: insufficient-funds declines used to land as `card_declined` instead of `insufficient_funds`; expired-card declines used to land as `invoice_expired` (the session, not the card); 3-D Secure timeouts used to be the catch-all `provider_error` instead of `authentication_failed`; and integration errors (a card session missing a required field) were hidden inside `provider_error` instead of being surfaced as a fixable integration mistake. The merchant-facing wording for `card_declined` was also rewritten — it previously said "declined by the issuing bank" even when the actual decline came from the acquirer's risk system. 1,471 historical rows were backfilled to the new codes so dashboard analytics and historical webhook re-fires line up with the new taxonomy.
May 21, 2026v1.75
  • fixCompleted Alipay (CNY) and WeChat Pay (CNY) transactions now appear in the Balances page and count toward withdrawable funds. Previously these rails were collected and settled correctly but were missing from the balance calculation, so the CNY net balance read as zero and merchants couldn't request a payout against it. Earnings are net of the 12% (Alipay) / 13% (WeChat Pay) all-in fee, with a T+1 settlement window applied per-transaction; CNY balances are paid out in crypto on the same rails as every other currency. Backfill is automatic — refresh the Balances page to see the corrected total. No action needed for merchants who weren't using these rails.
May 21, 2026v1.74
  • improvedCustomers who select the China region on the checkout page but whose device doesn't appear to be Chinese-capable (no Chinese locale, no China/HK/TW/SG timezone, no Alipay or WeChat in-app browser) now see a small heads-up message above the Alipay and WeChat tiles: "These options need the Alipay or WeChat app on your phone. If you don't have either, try a card or a different payment method." The tiles are not hidden — the detection is heuristic and the customer can still proceed — but this should noticeably reduce the abandonment rate on those rails for merchants whose audience is mostly outside mainland China. Available in all 5 checkout languages (EN/PT-BR/ES/RU/ZH-CN).
May 21, 2026v1.73
  • fixCard-brand outage failures no longer count against your success rate. Between 2026-05-15 and 2026-05-20 the upstream card acquirer experienced a Visa-side authorisation outage that rejected every Visa attempt with an opaque generic error — these aren't legitimate declines (the customer's card was fine, your integration was fine, the acquirer was the bottleneck). They've now been re-tagged with a stable `card_brand_outage` failure code and are excluded from the success-rate denominators on the Dashboard, the Payments page, and our internal admin views. The transactions themselves remain visible in your transactions list with their original status — only the aggregate success-rate calculation is corrected. Backfill applied to 1,287 historical Visa-attribution rows. Going forward, any future brand-side outage tagged with the same code will be excluded automatically; new Visa attempts are already blocked at the form level (see v1.72).
May 20, 2026v1.72
  • improvedTemporary card-brand outage: Visa cards are blocked at the card-payment form while the underlying card acquirer addresses a Visa-side processing issue. Customers attempting a Visa BIN now see an inline message asking them to use a Mastercard or pick another payment method — no transaction row is created and the attempt does not count against the merchant's success rate. Mastercard and other rails (PIX, C2C, SBP, Open Banking, Alipay, WeChat Pay, Crypto, Crypto On-Ramp, Telegram Stars) are unaffected. We'll publish a follow-up changelog entry as soon as Visa is re-enabled — no merchant action needed in either direction.
May 20, 2026v1.71
  • fixThe per-transaction Fee and Net Payout columns on the dashboard Payments table now display USD, matching their `$` prefix. Previously, on rails that settle in a non-USD currency (Alipay/WeChat Pay in CNY, PIX in BRL, C2C in ARS, SBP in RUB, Open Banking in EUR), those two cells were reading the native-currency fee figures and rendering them with a `$` sign — so a 12% Alipay fee on CNY 816 displayed as "$97.92" instead of the correct ~$14.36. Amount (USD) was already correct; only the Fee and Net Payout columns were affected. The downloadable transactions CSV now also carries USD fee and net-payout columns alongside the native ones, so spreadsheet totals add up correctly without manual FX conversion. Monthly invoice line items were on the same mis-aggregated source and have been switched to the USD figures in the same change. No integration changes needed — refreshing the dashboard shows the fix immediately.
May 20, 2026v1.70
  • improvedDashboard Total Fees and Net Payout now sum correctly when a merchant uses more than one rail in the same period. Previously the per-transaction fees were summed in their original currency (a EUR card fee and a CNY Alipay fee were added together as if both were USD), and Alipay/WeChat Pay transactions weren't recording their fees at settlement at all — so they appeared in Revenue but vanished from the Total Fees and Net Payout cards. Both are fixed: fees are now stored alongside a USD-normalized copy used for aggregation, and the settlement path always records them. Revenue minus Total Fees now equals Net Payout per the all-in rates published in /docs/providers. Historical transactions have been backfilled, so the change is visible immediately on the next dashboard load.
May 19, 2026v1.69
  • improvedPOST /v1/payments calls without `card_payment:true` no longer skip the multi-method checkout chooser. Since v1.65 the country-aware routing default would silently shortcut customers in supported card regions (EU/UK/US) straight to our hosted card form, even when the merchant hadn't explicitly opted into the card rail. As a result the payment-method toggles in the merchant dashboard (Card / Crypto / Crypto on-ramp / Telegram Stars / regional) were effectively bypassed for those customers. From this release, the auto-shortcut only fires when the merchant explicitly sends `card_payment:true` in the create-payment body. Without that flag, the customer lands on `/pay?session=…` and sees whichever methods the merchant has enabled in dashboard settings. Merchants who want their customers to go straight to the card form (Stripe-style) should set `card_payment:true` — that behaviour is unchanged. Merchants who want the chooser should drop the flag from their integration. No dashboard action needed either way.
May 19, 2026v1.68
  • improvedThe dashboard transactions page now shows the webhook reference id next to the dashboard id whenever they differ. When a customer switches payment method mid-checkout (e.g. picks card after starting on the crypto on-ramp), we settle the charge on a new internal transaction but our webhook fires with the original session id you POSTed to /v1/payments — so the id that appears in your DB doesn't match the id shown in the dashboard. The row now displays both: the dashboard's id (the internal settlement record) and a smaller "Webhook" id underneath (the value you'll find in your own database, matching payment_id / order_id in the webhook payload). The transaction-id search box also accepts either id and resolves both to the same row, so reconciliation works in both directions.
May 18, 2026v1.67
  • fixFollow-up to v1.65's country-aware routing: POST /v1/payments calls that route to the card-payment rail no longer require the merchant to also set `card_payment: true`. Previously, when routing picked the card-payment rail on the merchant's behalf, a downstream session creation would fail because the request didn't carry billing details (those are collected on our hosted card form, not on the create-payment call). Now the hosted-card shortcut applies whenever routing selects the card-payment rail, whether by explicit `card_payment: true` or by the country-aware default. Merchants whose card payments started erroring around 21:00 UTC on May 18 should be unblocked automatically with no integration changes.
May 18, 2026v1.66
  • improvedThe POST /v1/payments reference now documents the `card_payment` request field. It was already accepted by the API but undocumented. Setting `card_payment: true` forces the card-payment rail (settlement in fiat) instead of letting routing pick — useful when you want card processing for a specific call rather than the crypto on-ramp fallback.
May 18, 2026v1.65
  • improvedCard payments are now routed to the best rail for each customer's country by default, instead of falling back to the crypto on-ramp. If you send a payment with a customer country in our supported European card market (Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden, the United Kingdom, Switzerland, Norway, Iceland, or the United States), the Card Payments rail handles the charge. Brazil → PIX, Argentina → C2C, Russia → SBP are routed to the regional rail when the matching local currency is supplied. The crypto on-ramp is now used only when no card or regional rail can serve the customer. Merchants whose customers were being silently routed to the on-ramp and abandoning at the buy-crypto screen should see completion rates recover automatically — no integration changes required.
May 18, 2026v1.64
  • improvedThe billing State field on the card checkout form is now a US-only state dropdown (Alabama … Wyoming + DC) instead of a free-text field shown for every country. State only applies to US billing addresses on our acquirer, and a typo-prone free-text input was working against the auth-rate uplift the field was added for. US customers now pick from the 50 states, sending the USPS 2-letter code; non-US customers don't see the field at all and skip a step they'd otherwise be confused by. Switching billing country away from US automatically clears any previously selected state.
May 18, 2026v1.63
  • improvedThe US-IP requirement for US-billed card payments now also enforces on the inline server-to-server endpoint (POST /api/v1/checkout/{id}/card), not just the hosted-checkout fallback. Previously a stale UI client or direct API caller could submit a US-billing inline charge from a non-US IP, which would inevitably decline upstream or settle and chargeback. The new gate returns 403 US_IP_REQUIRED with the detected country in the body, matching the existing behaviour on /card-hosted. Test-mode API keys bypass the gate as before. The /pay UI tile and /pay/card server render already gate on the same eligibility signal, so customers won't normally reach this defense layer.
May 18, 2026v1.62
  • fixOpen Banking checkout no longer returns "Open Banking is not enabled for this site" for merchants whose sites are all OB-approved but whose API calls don't include a siteId. The site-level approval flag was only being checked when the transaction had a siteId attached; for merchants creating payments via API without specifying a site, we fell back to a legacy org-level flag that wasn't necessarily set even when every individual site was approved. Now, when a transaction has no siteId, we also accept the request if at least one site under the organization is OB-approved.
May 16, 2026v1.61
  • improvedUS-billed card payments now go through the inline server-to-server flow (no more hosted-checkout bounce). Our card acquirer advised that including the customer's billing state field meaningfully improves the authorisation rate on the US MID — so the card-checkout form now collects a State field, required when the billing country is United States and optional everywhere else. US customers stay on vexutopia.com (or the merchant's embedded /pay/card surface) through the 3D Secure step. The $10 US minimum and US-IP gate are unchanged. No merchant action needed; the change applies automatically to new sessions.
May 16, 2026v1.60
  • fixTest-mode return_urls are now expanded the same way as the live rails. The /pay/test simulate endpoint was redirecting to the raw return_url verbatim, so a merchant testing with `return_url: "https://merchant.com/payment-status"` (no placeholders) got sent back with no outcome attached and had to fall back on webhooks or GET /v1/payments to render the right UI. Now the test rail does the same expansion as the production rails (regional, crypto, card, China-pay): {payment_id}, {order_id}, {transaction_id}, {status} placeholders are filled in, and if the URL has no `status=` query param at all we auto-append `?status=<outcome>` (success | fail | cancelled | expired). Existing live integrations are unaffected — this only changes the test simulator's behavior to match production. The placeholder vocabulary is documented on /docs/payments.
May 15, 2026v1.59
  • fixCheckout-logo uploads now survive deployments. The upload route was writing the file only to the running server's working directory (an internal build snapshot), and our deploy process replaces that snapshot on every release — so any logo uploaded between deploys silently disappeared the next time we shipped (~3 deploys later in the worst case, due to snapshot retention). Now writes go to both the canonical source location (which every deploy carries forward) AND the live snapshot (so the new logo is visible immediately, no waiting for the next deploy). One affected merchant's logo has been recovered from the previous snapshot and re-published; if your logo went missing recently, please re-upload and it'll persist correctly going forward.
May 15, 2026v1.58
  • improvedReplaced the Visa trust-badge wordmark on the card checkout page with the official Visa brand mark — path-based SVG in Visa Blue (#1434CB) per the merchantsignage.visa.com brand guidelines, instead of an Arial Black text approximation. Reads as a recognized brand instead of a generic label and reinforces trust at the point of card entry.
May 15, 2026v1.57
  • improvedThe non-US inline card checkout page now locks the mobile viewport so customers can no longer pinch-zoom or accidentally double-tap into an unreadable zoomed view, and the iOS auto-zoom-on-input-focus is suppressed. Matches the convention used by Stripe, Adyen, and Checkout.com on their card-entry surfaces — a stable, fixed-layout form reads as more trustworthy and avoids the common confusion where a customer tabs into a field, the page zooms, and they can no longer see the rest of the form. The marketing pages and dashboard surfaces continue to allow scaling as before.
May 15, 2026v1.56
  • improvedAlipay and WeChat Pay checkout now shows the QR code on mobile too — not just on desktop. Previously the mobile flow showed only the "Open Alipay/WeChat" deeplink button on the assumption that the customer's phone is the device with the wallet app installed. That left two cases stuck: customers without the app installed (the deeplink button does nothing), and customers who'd rather scan with their tablet or another phone. The mobile page now renders the deeplink button as the primary action, then "或扫描下方二维码" ("or scan the QR below") with the QR underneath. Copy Pay Link button stays available as a third option. The redundant "show QR on another device" link at the bottom was removed since the QR is now visible by default.
May 15, 2026v1.55
  • fixReverted the second attempt at inline server-to-server processing for US-billed card payments — our card acquirer's upstream is still throwing a generic error on the MID they provisioned for us (same signature as earlier today, observed after their second "fixed" notification). We've sent them a fresh batch of failed transactions for diagnosis. US customers are back on the hosted-checkout flow — same vexutopia.com card page, same $10 minimum, same US-IP requirement. We'll re-enable inline S2S once the acquirer confirms successful test settlements on the new MID.
  • fixTurkey (TR) is re-added to the card billing blocklist for the same reason — TR shares the still-broken MID with US, so card payments from a TR billing address would fail upstream. We'll unblock again once the MID is healthy.
May 15, 2026v1.54
  • improvedUS-billed card payments are back on the inline server-to-server form (same as every other country) — our card acquirer confirmed the upstream issue is fixed and provisioned a new MID specifically for us. Customers stay on vexutopia.com (or your embedded /pay/card page) through the 3D Secure step instead of being bounced to an external hosted page. The US-IP requirement and $10 USD minimum are unchanged.
  • improvedTurkey (TR) is unblocked as a card billing country. The same new acquirer MID that handles US billing now also accepts Turkish billing addresses — so TR customers can complete card checkout from the inline form just like every other supported country. The minimum order amount for TR billing is $10 USD (matches the US floor — both share the acquirer MID). The country picker on hosted checkout, the embed/API pre-flight, and the merchant docs all reflect this automatically.
May 15, 2026v1.53
  • fixThe hosted regional checkout page (the one customers land on for PIX/C2C/SBP after you create a payment via the API) was throwing "Something went wrong" instead of rendering the payment page. A small helper function was being imported from a client-only React component file; under the App Router that turns the import into a non-callable proxy on the server, and the page render crashed before the payment form could load. Customers paying via Pix, Card-to-Card or SBP from a `checkout_url` we returned to a merchant would see the generic error page even though their underlying payment was created cleanly with the acquirer. Moved the helper into a server-safe module so the page renders normally for all three regional rails.
May 15, 2026v1.52
  • improvedAlipay and WeChat Pay checkout now offers a one-tap "Copy Pay Link" button alongside the QR code and the open-in-app button. Customers paying from a single device — where they can't scan their own screen — can now copy the alipays:// or weixin:// payment link and paste it inside the Alipay/WeChat in-app browser to continue. Also helpful for desktop customers who'd rather text the link to their phone than aim a camera at their monitor. Includes a clipboard fallback for older Android WebViews and a clear "Copied" confirmation state.
May 15, 2026v1.51
  • fixReverted the brief switch to inline server-to-server processing for US-billed card payments. Our card acquirer is currently throwing a generic upstream error on a meaningful share of US-billing attempts (same signature as the late-April upstream cluster); we've reopened the ticket. US customers are back on the existing hosted-checkout flow — same vexutopia.com card page, same $10 minimum, same US-IP requirement. We'll re-enable the inline flow once the acquirer confirms the upstream is stable.
May 15, 2026v1.49
  • fixTurkey (TR) is no longer accepted as a card billing country. Our card acquirer confirmed the MID does not support Turkish billing, so card checkout from a TR billing address would always be declined at the acquirer. The country picker on hosted checkout, the embed/API pre-flight gate, and the merchant docs all reflect the change automatically. Customers in Turkey can still pay via crypto on-ramp or other rails.
  • fixRe-stated the failure reason on four historical Turkish card-payment attempts after the acquirer reconciled them: an amount-below-minimum (re-classified to EXPIRED), a last-name-validation decline, a blocked-issuing-bank decline, and an unsupported-card-type decline (only Visa and Mastercard are accepted). Each row now carries an accurate, customer-actionable failure reason instead of the generic wording that came back on the original webhook.
May 14, 2026v1.48
  • improvedThe 1-payout-per-7-days cooldown is now enforced per payment method instead of per organization. Earning through multiple rails (e.g. Telegram Stars + PIX + Card Payments) means each rail has its own weekly cooldown — a Stars payout request no longer locks out a PIX or Card Payments request the next day. The 7-day window is unchanged within a single method.
May 14, 2026v1.47
  • fixReclassified 1,657 historical card-payment rows out of FAILED into EXPIRED. These rows weren't real card declines — they were sessions the customer literally couldn't complete because of three different upstream/internal issues that have since been fixed: (a) a 48h authentication outage at our card acquirer on 2026-05-04 to 2026-05-06 that broke 815 sessions; (b) a 2-day upstream outage on 2026-04-26 to 2026-04-27 that surfaced as a generic transaction error on 164 sessions; (c) an internal name-sanitization bug active 2026-04-25 to 2026-04-27 that broke 188 sessions; and (d) 490 sub-floor amount attempts that the pre-flight gate (added 2026-05-08) now rejects upfront. The dashboard's failed-payments count drops by ~28% accordingly. Conversion rate (completed/total) is unchanged because EXPIRED rows still count as attempted; we may follow up on showing a 'settled rate' that excludes abandonment from the denominator.
  • fixThe card-payment rail's webhook failure_reason field sometimes contained a raw machine-readable status record instead of an actual error message — 48 transactions carried one as their failureReason, surfaced verbatim on dashboards. The sanitizer now extracts a real message if one is present, or substitutes a clean generic decline message. Re-cleaned the 48 historical rows in the same pass.
May 14, 2026v1.46
  • fixPayment-method tabs and per-method charts on Dashboard → Overview and Dashboard → Transactions now always include any method you have historical revenue in, even if you've turned that method off on hosted checkout. Previously, hiding Telegram Stars (or any other rail) from the hosted checkout also hid it from your transaction tabs and stats — which made revenue earned via the direct API invisible in the dashboard. Visibility is now driven by 'do you have completed transactions in this bucket?', independently of the hosted-checkout toggle.
May 14, 2026v1.45
  • fixCard payment failures now always carry a programmatic failure_code on the persisted Transaction row (and therefore on dashboard rows + GET /v1/payments responses). Previously about half of card-payment failures had failure_code=null because the synchronous catch blocks in the /card and /card-hosted routes wrote failure_reason but skipped the classifier. New writes go through the classifier, and we backfilled 3,637 historical FAILED rows so existing dashboards and analytics are consistent. The classifier itself was also extended to recognise more upstream decline patterns: missing or blocked billing country, unsupported payment method, BIN and repeated-failure blocks, generic declines, and amount-below-limit variants are now mapped to the appropriate code (card_unsupported / card_declined) instead of the catch-all provider_error.
  • fixInternal payment-processor brand names are now scrubbed from the persisted failureReason on the inline /api/v1/checkout/{id}/card path. The hosted path already scrubbed; the inline path was passing the raw upstream error string through, which could surface a vendor name on the merchant dashboard. Backfilled 58 historical rows to remove leaked names from older transactions.
  • improvedCustomer-facing card-decline copy now covers more upstream decline patterns that previously surfaced verbatim or as the generic catch-all message: blocked cards, bare failures, declines returned with no detail, and processor malfunctions all now render as a clean 'Card declined. Please try a different card or another payment method.'
  • improvedWebhook endpoints that return 404 or 410 (URL gone, route never existed) on five consecutive deliveries are now auto-disabled. Other failure modes (5xx, 401/403, network timeouts) are intentionally NOT auto-disabled because they may resolve. Disable creates an entry in AuditLog with the URL and the recent response codes; the merchant can re-enable from the dashboard once they fix the URL. We also disabled one already-known dead ngrok endpoint that had been collecting 22 consecutive 404s.
May 14, 2026v1.44
  • fixPOST /api/v1/checkout/{id}/card-hosted now returns the same structured 400 CARD_PAYMENT_INTEGRATION error as POST /v1/payments when the upstream card acquirer rejects because billing/name fields weren't supplied. Previously it returned a generic 422 with a text-only message, which embed/direct-API integrations couldn't programmatically detect — so a misconfigured client would keep retrying the same broken payload (we observed one customer hit this same error 17 times in a single afternoon). The new response includes a stable error code, a doc link, and an actionable message; the row's failureReason is also rewritten so it shows up usefully in the admin dashboard. Behaviour for everyone else (correct integrations, real upstream declines) is unchanged.
May 14, 2026v1.43
  • fixSession timeouts and customer cancellations are no longer mislabeled as "failed". Several rails (notably card payments and the crypto on-ramp) reported every non-success outcome as a failure — including invoice expirations, session timeouts, and customer-initiated cancellations. We now inspect the failure reason and reclassify these to the correct terminal status before persisting. A transaction whose checkout session timed out without the customer paying now resolves to `expired` (matching the existing terminal status used by direct-create expirations), and customer-cancelled intents resolve to `cancelled`. This affects the dashboard transactions table, GET /v1/payments responses, customer-facing checkout polling, and the webhook `event` / `status` fields (you'll now receive `payment.expired` instead of `payment.failed` for sessions the customer never paid). Genuine card declines, 3DS failures, BIN blocks, and upstream HTTP errors during session creation continue to fire `payment.failed` exactly as before. We also backfilled ~977 historical transactions whose status was incorrect under the old logic — your dashboard's failed-payments count and your own analytics derived from our webhooks may both go down accordingly.
May 14, 2026v1.42
  • fixJapan (JP) is now in the card-billing country blocklist. Our card acquirer confirmed their MID does not support JP billing addresses, so any card_payment attempt with country:"JP" was reaching the upstream and getting silently declined. The block now fires earlier — the JP option is hidden from the country dropdown on /pay/card and the embedded checkout, /pay's Card Payments tile is hidden when the customer's region resolves to Japan, and POST /v1/payments with card_payment:true + country:"JP" returns 422 NO_PROVIDER_AVAILABLE instead of bouncing off the acquirer. JPY remains a supported invoice currency — only the billing-address country is restricted; non-JP customers paying in JPY are unaffected. The full blocklist is rendered live on /docs/providers.
May 14, 2026v1.41
  • improvedDocs overhaul. We audited every page and fixed several factual mismatches that could mislead integrators: the Card Payments fee in the providers summary table now matches the detailed section below it (it previously showed an incorrect figure); the Payments page now lists every merchant-facing status (added cancelled and partially_refunded, removed a duplicate pending row); the supported-currency list on the Payments page now correctly includes CNY everywhere (one callout was missing it); the Telegram Stars page now shows the correct volume tier breakpoints ($0/$100K/$200K/$500K → 5/4/3/2%) instead of the wrong $10K/$100K/$1M numbers; the Resend Webhook section now correctly says 60 requests per minute per API key (was incorrectly listed as 10 per hour); and the updated_at field is now documented in the Payment object table to match the JSON examples.
  • improvedEmbedded Checkout docs now include the v1.40 US-IP requirement (US-billed card payments need a US-IP customer; gate fires on both the redirect-to-checkout_url path and the /card-hosted call), and the events list now mirrors the example snippet so it's clear which three events are essential vs. which two are optional polish.
  • improvedDocs sidebar now expands the active page into its own anchored sub-navigation. Open any long page (Payments, Providers, Webhooks, Errors) and the section list appears under the page name in the left rail — click directly into Idempotency, Verifying signatures, US IP requirement, etc. without scrolling. Same anchored TOC also renders inline at the top of each long page for mobile and search-engine readability. The introduction page now links the Telegram Stars docs from the API reference grid (was previously only reachable from the sidebar), the Quick Start step 2 has been rewritten so it actually works on a fresh API key (the old version sent the merchant to a 404), and the orphan SDKs page (which advertised a roadmap that didn't exist) has been removed.
May 13, 2026v1.40
  • improvedUS-billed card payments now require the customer to be on a US IP address. Our US card acquirer treats geo-mismatched card sessions (US billing from non-US connections) as high-risk: the majority decline upstream, the small fraction that settle disproportionately chargeback, and merchants get billed for both. The gate fires in three places: (1) the /pay hosted checkout hides the Card Payments tile when the customer's region resolves to US but their IP isn't US, replacing it with an inline message explaining why; (2) the /pay/card page renders a clear refusal screen if the customer reaches it directly; (3) POST /api/v1/checkout/{id}/card-hosted returns 403 US_IP_REQUIRED with the detected country in the body. Sending country:'US' + card_payment:true on POST /v1/payments still succeeds — the gate only fires when the customer's browser actually visits the hosted page, since the API call originates from the merchant's server. Test-mode API keys (vex_test_*) bypass the gate so integration testing works from any region. Anonymized connections (Tor/VPN that strip the country code) are blocked alongside non-US — fail closed by design. New error code US_IP_REQUIRED documented at /docs/errors and /docs/payments.
May 13, 2026v1.39
  • improvedCard Payments setup is now one click instead of two. Previously, getting card payments live required (a) admin approval, then (b) the merchant separately finding and flipping a second toggle called "Card Payments on checkout.vexutopia" before the per-method toggle would un-grey. Several merchants were getting stuck on step (b). Now, when an admin approves a merchant for card payments (org-level or per-site), the hosted-checkout master switch is auto-enabled at the same time — so the per-method toggle is immediately usable. We've also renamed the master switch to "Show Card Payments tile on hosted checkout" so it's obvious it's the gate for the row below, and updated the greyed-out tooltip to point at the new name.
May 13, 2026v1.38
  • improvedClarified the difference between payment_method:"card" and payment_method:"card_payment" in the docs. They both let your customer pay with a card but they're different rails and you settle in different assets: card = crypto on-ramp (settle in USDT), card_payment = direct card processing (settle in fiat USD). A new comparison table on /docs/payments spells out what each one is, how to request it, and what countries it covers — and the field descriptions in the response/webhook payload tables now explain both inline so you don't have to scroll. No code or API change; same enum values as before. We also clarified that if you send card_payment:true for a country we don't yet cover with direct cards, you get 422 NO_PROVIDER_AVAILABLE — we never silently fall back to the on-ramp.
May 13, 2026v1.37
  • fixPOST /v1/payments with card_payment:true now returns a clean 400 CARD_PAYMENT_INTEGRATION error when the merchant sends billing fields (firstName / lastName / billing.*) on the create call instead of collecting them from the customer on our hosted card form. Previously the raw adapter exception text "Card session missing required field 'firstName'" bubbled out as a generic 422 PROVIDER_ERROR with no guidance on how to fix it. The new response includes the request fix, a doc link (https://vexutopia.com/docs/payments#card-payment), and a stable error code merchants can switch on. The error is also now correctly mapped through the customer-facing translator on /api/v1/checkout/{id}/card so a customer hitting it (e.g. via embed) sees "Card payment integration error" wording, not the raw internal field name.
  • improvedAdded a copy-paste card-payment example to /docs/payments. Previously the page listed all the request fields generically but had no end-to-end snippet showing how to take a card payment — merchants were guessing whether to send firstName, billing, card details, or just the bare amount + email. The new "Card payments — copy-paste example" block (anchored at #card-payment) shows the exact curl request, the response shape, and explicitly calls out which fields NOT to send. Also documented the new CARD_PAYMENT_INTEGRATION error code in /docs/errors with a link back to the example.
May 12, 2026v1.36
  • newAdmin → Payouts now lists merchant and affiliate payouts in a single unified queue. Previously, affiliate payouts only surfaced on each partner's detail page (/admin/partners/[id]), making it easy to miss new affiliate requests when batch-processing merchant payouts. The queue adds a 'Type' column (Merchant vs Affiliate chip) and a 'Source' column that shows the org for merchant rows or the partner name + referral code + email for affiliate rows. Affiliate rows skip the per-currency Method/Period columns (affiliate payouts are USD-only, settling in stablecoin like USDT-TRX). All existing filters (REQUESTED / PROCESSING / COMPLETED / REJECTED) and live FX→crypto estimates work for both types. Approve/reject actions route to the correct backend automatically based on row type.
  • fixAffiliate payout modal no longer errors with a raw 'bad_body' message when the available balance carries more than 2 decimal places. The Max button (and the modal's initial amount) used to copy the full-precision available balance into the input (e.g. 161.93825), but the server-side schema validates against ^\d+(\.\d{1,2})?$ — anything with 3+ decimals was rejected with HTTP 400 / 'bad_body'. The modal now floors the prefilled amount to 2 decimals (so 161.93825 becomes 161.93, which is always ≤ the actual available balance), strips any extra decimals the user types or pastes, and the previously-unfriendly 'bad_body' error is now mapped to a clear sentence.
  • fixRetired one of the swappable crypto on-ramp providers that had been registered with sandbox/test credentials, so live merchant traffic was being routed to a sandbox URL — no transactions could complete (0 of 23 historical attempts settled). The integration was inherited from the April pre-cleanup snapshot as one of several swappable on-ramp providers but never wired up to production credentials. A merchant flagged it after a live customer was routed to a sandbox widget. The provider has been disabled and removed from the routing rotation; the underlying DB row is retained so the 23 historical transactions still resolve their merchant-facing `processor` field on the dashboard. Customers picking the crypto on-ramp now route through the production-credentialed provider as intended.
May 12, 2026v1.35
  • improvedBranded error pages now replace the unstyled 'Internal Server Error' that customers occasionally saw during a deploy. Three layers were added: (1) src/app/global-error.tsx catches the case where even the root layout fails to render — full-screen Vexutopia-branded page with 'Try again' and 'Back to home' actions and the request digest for support; (2) src/app/error.tsx catches non-fatal errors that happen inside the root layout (uses the site theme tokens, fits the existing page chrome); (3) the static /502.html that nginx serves when the upstream is briefly unavailable (during PM2's rolling worker reload) was replaced with a matching Vexutopia-branded version that auto-polls / HEAD every 4 seconds and reloads as soon as the worker is back. Customer-visible window during a deploy is now either invisible (the auto-poll kicks in) or shows a polished page instead of the bare 'Internal Server Error' default.
  • fixDashboard overview no longer hides revenue for payment methods whose Settings → Method-enables toggle is OFF. The 'Method enables' toggle is for *checkout visibility only* — it should never hide historical revenue from the dashboard, but two surfaces were doing exactly that: (1) the Transaction Volume chart silently dropped the bar series for any method whose toggle was off, so the hover-total under-reported each day; (2) the per-method breakdown cards (one tile per rail) also omitted methods whose toggle was off. Both now render the union of currently-enabled methods and any method with revenue in the visible window, so the totals always match what was actually collected. Concretely: a merchant who turned off the Telegram Stars checkout tile but kept taking Stars via an existing bot integration now sees that Stars revenue back on the chart and breakdown.
  • fixTelegram Stars direct-integration API (POST /api/v1/payments/telegram-stars) no longer rejects requests when the Settings 'Telegram Stars' toggle is off. The toggle's only job is to hide the Stars tile from your hosted checkout — direct API calls (used by Telegram bots that build their own pay flow) should keep working regardless. Previously, flipping the checkout tile off also returned 403 TELEGRAM_STARS_DISABLED to bot integrations, silently killing Stars revenue until the toggle was flipped back on. The API now gates only on the TON payout wallet being configured (the actual settlement prerequisite) and the platform allowlist when active. TELEGRAM_STARS_DISABLED has been removed from the docs error table.
May 12, 2026v1.34
  • improvedSoftened the customer-facing wording for the upstream acquirer's catch-all decline. The acquirer returns a single opaque error that bundles several risk rejections (BIN block, geo mismatch, velocity throttling, disposable email, etc.); the previous translation pinned the blame on the customer's email address ("use a real email address (disposable email services aren't accepted)"), which misled customers who were declining for unrelated reasons — a real merchant flagged this when a customer on a legitimate @gmail.com address kept seeing the email-blame message despite the actual cause being elsewhere. The new wording leads with the generic decline ("Card declined by our risk system. Try a different card, or wait a few minutes before retrying") and only mentions disposable email as a conditional aside ("If you're using a temporary or disposable email address, switch to a permanent one"). Customers with legit emails now get actionable guidance for the more likely causes (issuer-specific BIN block, velocity limit).
May 12, 2026v1.33
  • improvedDocumentation now covers the US card hosted-checkout path for embedded and direct-API integrators. Previously the only mention of the US restriction was a single sentence in /docs/providers, which covered the standard hosted /pay flow but left embedded-card merchants stuck — calling /api/v1/checkout/{id}/card with a US billing address returns 400 US_REQUIRES_HOSTED, and the /card-hosted endpoint that resolves it had zero public docs. The /docs/embed page now has a "United States billing — falls back to hosted page" callout right after Prerequisites, with two integration options (redirect to checkout_url, or POST to /card-hosted yourself). The /docs/providers page now includes a full /card-hosted reference under the existing US block — request body, response shape, the ~3.5-minute session reuse window, and the $10 USD minimum. The /docs/payments page has a one-line note next to checkout_url pointing US-handling readers to the new sections. The hosted card page is served on vexutopia.com — the customer's URL bar never leaves vexutopia.com.
May 11, 2026v1.32
  • improvedBREAKING (status naming) — the "processing" status is gone from every merchant-facing surface (API responses, webhook payloads, the dashboard transactions table, the customer-facing checkout poll endpoint, and the docs). The status field now returns "pending" for any in-flight transaction that hasn't reached a terminal state. Reason: "processing" implies "you took my money and it's settling", which misleads customers and support whenever a session is created and the customer hasn't actually paid — they see their bank holding the card auth, the merchant dashboard saying "processing", and reasonably conclude the merchant has their money. The merchant-facing status vocabulary is now: pending, completed, failed, cancelled, expired, refunded, partially_refunded. Terminal statuses are unchanged. If you're filtering on status=processing in your integration, switch to status=pending — it covers everything that was processing. If we later need to distinguish "awaiting customer payment" from "customer paid, awaiting upstream confirmation", we'll add a separate field; for v1 both cases live under pending.
May 11, 2026v1.31
  • improvedCard checkout (non-US inline form on /pay/card) now shows a subtle 'Powered by Vexutopia' line below the SSL / VISA / Mastercard / 3D Secure trust badges. Previously only visible to customers checking out via the embedded card flow on the merchant's own site; now it also anchors the standalone Vexutopia-hosted card page, matching the conventional placement used by Stripe, Adyen, and Square. Same styling on both surfaces; the link opens vexutopia.com in a new tab from embeds and the current tab from the standalone page.
May 11, 2026v1.30
  • improvedCard-payments minimum order amount is now country-aware. US billing addresses require a minimum of $10 USD (sub-$10 US charges are rejected upstream); all other countries continue to accept from $7 USD. The gate runs in three places — the /pay UI hides the card tile and shows the country-specific minimum, POST /v1/payments returns AMOUNT_BELOW_MINIMUM (HTTP 422) up-front with the relevant floor in the message, and the per-session /api/v1/checkout/{id}/card and /card-hosted routes reject below-floor amounts before opening a session. Docs updated under /docs/providers (Card payments) and /docs/errors (AMOUNT_BELOW_MINIMUM).
May 11, 2026v1.29
  • fixUS hosted card checkout no longer fails with an expired-session error when the customer takes more than 5 minutes to fill in the card form. A hosted card session is only valid for 5 minutes, but our idempotency window cached the session for up to 1 hour — so a customer who came back to /pay after the session expired (whether by retry or a slow first attempt) was handed back the same dead checkout URL. Idempotency now respects the session lifetime: we only reuse an existing hosted session if it was created less than ~3.5 minutes ago (leaves a 90s submit buffer). After that, the stale child is marked EXPIRED and a fresh session is minted on the next click. The customer just clicks "Pay" again from /pay and gets a working 5-minute window.
May 11, 2026v1.28
  • fixPOST /v1/payments with card_payment:true now works end-to-end. Previously the returned checkout_url (/pay/card?session=...) silently redirected the customer to the multi-method picker because the page enforced a separate per-Site "standalone" dashboard toggle most merchants don't have on. The page now honours card_payment:true sessions on its own — explicit API opt-in is enough; you no longer need to also flip a dashboard toggle. For US billing, /pay/card now skips the inline card form entirely (the US acquirer is hosted-only — the inline form was unreachable anyway) and auto-redirects the customer to the secure hosted card page in ~1 second. Merchants who were working around this by manually POSTing to /api/v1/checkout/{id}/card-hosted no longer need to — just send the customer to the checkout_url we return and the rest is handled.
May 11, 2026v1.27
  • fixFollow-up audit closing remaining merchant-facing surfaces where an internal payment-processor name could leak. GET /v1/transactions now returns the brand-neutral rail code in the `provider` field instead of the internal routing identifier; webhook delivery for FAILED transactions persists a scrubbed failureReason to the database; the checkout status poll endpoint scrubs the failureReason on read as defense in depth; the merchant dashboard transactions list strips internal routing metadata before serialization; the test-mode simulate endpoint strips internal metadata before firing the merchant webhook; the crypto on-ramp's underpayment-handler no longer embeds the upstream processor's name in the persisted reason; and direct-charge error paths across the regional, card-payment, Alipay/WeChat Pay, and Telegram Stars rails now route their captured exception messages through the same brand scrubber. A new regression test feeds branded synthetic data through each of these endpoints and asserts no processor name survives in the serialized response.
May 11, 2026v1.26
  • fixPOST /v1/payments with card_payment:true no longer attempts to charge a card the merchant hasn't supplied. Previously the call would return PROVIDER_ERROR "missing required field firstName" because the route was driving the synchronous direct-charge path with no card and no billing details — fields that are collected from the customer on our hosted card form, not from the merchant's server. The endpoint now returns checkout_url pointing at the Vexutopia-hosted card page (https://vexutopia.com/pay/card?session=tx_...) and the upstream session is created when the customer submits the billing form, matching how every other rail behaves (PIX, C2C, SBP, Open Banking, Alipay, WeChat Pay). Merchants integrating card_payment:true should redirect the customer to the returned checkout_url; do not send firstName / lastName / billing address fields on the create call.
  • fixProvider error responses no longer leak the internal name of the underlying card-payment, regional, or Alipay/WeChat Pay processor. Previously a failed POST /v1/payments could return message:"<processor brand>: ..." or persist a failureReason starting with the upstream processor's name, which then surfaced on the dashboard Payments tab. All such strings are now scrubbed to the neutral "payment processor" at the API boundary, the persisted failureReason is scrubbed before save, and the adapter source strings themselves are brand-neutral. Internal logs retain enough detail for debugging via stack traces.
May 11, 2026v1.25
  • newTransactions tables now have a Country filter on both the merchant dashboard (Payments tab) and the admin transactions view. Enter a 2-letter ISO code (BR, GB, US, RU, …) to narrow the list to payments from that country, alongside the existing status / method / email / date filters. The input is normalised server-side, so "uk" becomes "GB" and unknown codes fall through cleanly. Pairs with the Country column shipped in v1.22.
  • improvedAffiliate payout minimum lowered from $500 to $50 USD per request. Same one-request-per-7-days rate limit applies. The new minimum is enforced both client-side (modal validation) and server-side (POST /api/dashboard/affiliate/payouts), so existing affiliates with a balance between $50 and $500 will see the "Request payout" button become enabled immediately.
  • improvedAffiliate dashboard — every USD figure (available balance, earned, matured, maturing, paid out, per-method totals, payout amounts, recent payouts row) is now displayed at exactly 2 decimal places. Previously some accumulated values surfaced with sub-cent precision (e.g. "$41.20825"), which was easy to misread as "$41,208.25" if you parse the period as a thousands separator.
  • improvedAffiliate dashboard — the per-method breakdown column previously labelled "Rate" is now "Platform fee", with a small "× <split>% you" subtitle directly under each rate so it's immediately visible that the displayed percentage is Vexutopia's fee on the merchant, not the affiliate's commission. The intro paragraph and "Show formula" panel now spell out that the affiliate receives a fixed share (typically 50%) of that platform fee, and show the effective commission rate (e.g. 2.5% of volume on a 5% rail). Same numbers as before — just no longer ambiguous.
May 10, 2026v1.24
  • fixCard billing addresses now go through the same transliteration pipeline as cardholder names. Previously only first/last name were normalised — billing line1/line2/city/postal-code were forwarded raw to the card acquirer, so any non-ASCII character (Japanese kanji, Korean Hangul, Cyrillic, accented Latin, the 〒 postal symbol) tripped the acquirer's field validation and the charge silently 400'd. Now "東京都渋谷区1-2-3" / "Müllerstraße 12" / "〒100-0001" become "Dong Jing Du Shi Gu Qu 1-2-3" / "Mullerstrasse 12" / "100-0001" before being signed and sent. Customer keeps typing in their native script; the upstream sees ASCII. Applies to both the inline /pay card form and the hosted-card direct API.
May 9, 2026v1.23
  • improvedFailure reason on the dashboard Payments tab is now translated into short, actionable English instead of the raw upstream string. Previously a card declined for a regional block surfaced with confusing upstream wording that referred the reader to a support team that wasn't ours. It now reads "Card not supported by the acquirer (BIN, card type, or billing country restriction)." Issuer-side policy declines become "Card declined by the issuing bank."
  • newDocs — added a dedicated /docs/telegram-stars page covering the direct Stars integration. POST /api/v1/payments/telegram-stars returns a real t.me/$invoice/... link you can attach to a bot button or mini-app, so customers pay inside Telegram without ever seeing a Vexutopia checkout page. Page documents prerequisites (LIVE key, org-level enable, TON wallet), request/response shape, the Stars-specific error codes (TELEGRAM_STARS_LIVE_ONLY, TELEGRAM_STARS_DISABLED, etc.), and clarifies that Stars settle in TON to your TON wallet — separate from the USDC payout pipeline used by every other rail.
  • fixTelegram Stars — both the direct API endpoint (POST /api/v1/payments/telegram-stars) and the on-checkout switch route now correctly gate on your TON wallet, not your USDC wallet. Stars settle in TON, so the previous USDC check could block a Stars-ready merchant who had a TON address but no USDC address (or, worse, persist the wrong payout address on the transaction). The dashboard Settings UI was already correct; only the API had drifted.
May 9, 2026v1.22
  • improvedTransactions table now shows a Country column (flag + ISO alpha-2 code) for each payment, sourced from the customer's billing or detected region at checkout. Available on both the merchant dashboard's Payments tab and the admin transactions view, and exported as a new CUSTOMER COUNTRY column in the merchant CSV. Rows from older sessions where region wasn't captured display an em-dash.
  • improvedCountry fill-rate on payments improved — the regional payment pages (PIX / SBP / C2C, Alipay / WeChat, crypto on-ramp) now stamp the payer's country from the edge IP geolocation header on first visit, when the merchant didn't supply one on POST /v1/payments. Previously these direct-integration sessions stayed null because they bypass our /pay region-selector. Country values supplied by merchants or chosen by customers are never overwritten.
  • fixCountry codes are now normalised to ISO 3166-1 alpha-2 on every write path (POST /v1/payments, card billing form, region-selector). Previously a merchant passing country: "UK" got stored verbatim and rendered as boxed letters in the dashboard because U+K isn't a valid flag-emoji sequence — the canonical code for the United Kingdom is "GB". Existing rows with "UK" were backfilled to "GB".
  • improvedTelegram Stars now has a real on/off toggle in Settings → Payment Methods, matching the other rails. Previously the row only displayed an "active" badge and the only way to disable Stars at checkout was to clear the TON wallet entirely. The toggle is interactive once a TON payout wallet is on file and can be flipped off any time without losing the wallet configuration; turning it back on requires the wallet still be present.
May 9, 2026v1.21
  • fixDocs — Errors page rewritten to match the actual API response shape. The error envelope is flat ({ error, code, details? }), not the nested { error: { code, message, param, doc_url } } the page used to show — handlers written from the old example would have crashed with `data.error.code is undefined`. Codes are UPPERCASE_SNAKE_CASE (MISSING_API_KEY, VALIDATION_ERROR, RATE_LIMITED, NO_PROVIDER_AVAILABLE, etc.), not lowercase. Removed a handful of fictional codes (payment_failed, insufficient_funds, card_declined) that never existed; added the real ones we throw (REVOKED_API_KEY, EXPIRED_API_KEY, ACCOUNT_SUSPENDED, INSUFFICIENT_SCOPE, INVALID_BODY, VALIDATION_ERROR, NO_PROVIDER_AVAILABLE, PROVIDER_ERROR, PROVIDER_UPSTREAM_UNAVAILABLE, WALLET_NOT_CONFIGURED, DIRECT_MODE_UNSUPPORTED_CURRENCY) with their actual HTTP status codes.
  • fixDocs — Errors page rate-limit section corrected. The real per-API-key limit is 300 requests per minute (sliding window), single tier — not the previously-documented 100/min test + 1,000/min live (which never existed in code). Removed references to X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset response headers that we don't actually set; documented the Retry-After header (in seconds) we do set on every 429.
  • fixDocs — Webhooks page now correctly states that the top-level id field on every webhook payload equals payment_id and order_id (all three are aliases for your root session ID). The previous "id is the child rail" warning was outdated — that was fixed on May 9 — and was confusing merchants who saw the three fields actually match in their logs. Historical pre-2026-05-09 behaviour is called out separately for context.
  • fixDocs — base URL corrected in /docs/sdks, /docs/embed, and the Errors page JS example. Several snippets pointed at https://api.vexutopia.com/v1 which has never resolved; the canonical base is https://vexutopia.com/api/v1 (the apex domain), as already shown elsewhere in the docs.
  • fixDocs — removed /docs/customers entirely. The page documented a Customers API (POST /v1/customers, etc.) that has never existed in code — there's no Customer model and no /v1/customers/* route. Customer details are passed inline on POST /v1/payments via customer_id, customer_email, and customer_name. Nav and getting-started cards updated to match.
May 9, 2026v1.20
  • newPOST /v1/payments now accepts a card_payment: true boolean to pin a session to the direct card-payments rail (USD / EUR / GBP / CHF / PLN). Mirrors the existing crypto:true and direct:true opt-ins, and gives merchants a clean way to bypass the default routing order — which sends bare USD sessions to the Crypto-On-Ramp rail — without ever naming an underlying processor. Subject to per-Site card-payments approval and the $7 USD minimum; you'll get a structured 422 if either gate isn't met.
  • fixDocs — swept stale Authorization: Bearer ... examples out of /docs/customers, /docs/sdks, /docs/embed, and /docs/errors. The API only accepts X-API-Key (always has); the Bearer copy was stale and would have caused 401s for any merchant copy-pasting from those pages. Authentication, getting-started, and direct-payments docs were already correct.
May 9, 2026v1.19
  • newWebhook endpoints can now be scoped to a specific environment — Live only, Test only, or Both. Previously every registered endpoint on an organisation received every event regardless of which API key (vex_live_… or vex_test_…) created the underlying transaction, so merchants who run separate stage and prod stacks would see test-key payments fan out to their production webhook URL (and vice-versa). New endpoints created via the dashboard or POST /v1/webhooks default to live; existing endpoints are migrated with mode=both to preserve their current behaviour. Change an endpoint's environment any time from the dashboard or via PATCH /api/organizations/{orgId}/webhooks/{webhookId} with {"mode":"live|test|both"}.
  • newEvery outgoing webhook payload now includes a top-level livemode boolean — true for transactions created with a live key, false for test-key transactions. Lets handlers that listen on a single endpoint (mode=both) branch cleanly between environments without inferring it from the API key prefix or URL pattern.
May 9, 2026v1.18
  • newLocalized checkout — the customer-facing /pay flow now renders in the payer's regional language: Portuguese (Brazil), Spanish (Argentina / LATAM), Russian, and Simplified Chinese, with English as the global / EU / US default. Locale is bound to the region pill at the top of the page, so changing the region also switches the language without a reload. Coverage spans every customer-visible surface: the main /pay entry (region selector, total, Paying / Order rows, Pay-via dropdown, all CTAs and loading states, customer info form, error toasts, the "How does this checkout work?" drawer, trust footer), the regional rail pages (PIX, SBP, C2C, Open Banking), the China supplier list (Alipay / WeChat tiles), the crypto on-ramp wrapper, the card-processing overlay (success / failure / decline copy), and the /pay/result success page reached after payment.
  • newIndicative local-currency line on the total — payers in BR / AR / RU / CN now see an "≈ R$ 48.20 · charged in USD" line under the canonical USD amount, helping them anchor on a number they recognise. The actual charge is still denominated in USD; the local figure is informational only and uses a 6-hour-cached mid-market rate.
  • newFX rate endpoint — GET /api/fx/rate?to=BRL|ARS|RUB|EUR|CNY returns the current USD-base rate with a 6h server-side cache and graceful fallback to a hard-coded last-known rate when the upstream provider is unreachable. Used internally by the indicative-currency line; safe for read-only consumption by merchants too.
  • improvedLocale propagation across redirects — when /pay redirects to a downstream rail page (regional / crypto / card-processing / cn) it appends ?locale= and writes a path-scoped vex-checkout-locale cookie so the language survives the round-trip through the payment page and the /pay/result success card renders in the payer's language.
May 8, 2026v1.17
  • fixOne payment, one ID across the entire lifecycle. When a customer switches payment methods on the hosted checkout (e.g. tries card, abandons it, pays via PIX) GET /v1/payments/{your_id} now always returns the effective state of that single payment — completed, failed, or processing — directly off the ID we originally returned to you. Previously the endpoint could surface an internal "cancelled — Superseded by [rail] regional payment" state for the original session and a separate response for the rail that actually settled, forcing merchants to track multiple IDs. The internal supersession marker text has been scrubbed from API responses entirely. Applies to every rail (PIX, C2C, SBP, Open Banking, card, Alipay, WeChat Pay).
  • fixpayment.failed webhooks for mixed-checkout payments now carry your original session ID in payment_id / order_id plus your original metadata. Previously, a failed leg of a switched payment fell through to an internal child ID and stripped metadata down to internal fields — only payment.completed had the correct correlation. Both events now use the same rules: write your handler once, lookup by payment_id (or order_id), and it works for every status and every rail. Backward compatible — both fields were already documented for the success case.
  • fixClosed a leak where some internal routing fields (provider markers, raw upstream checkout URLs) could surface in GET /v1/payments/{id} responses for child rows. The internal-field cleanup rules are now unified across webhook delivery and API responses — single source of truth, audited on every change.
  • improvedCard Payments — USA-region customers now see the "Pay with Card" tile correctly on /pay. Regression from the May 8 1.16 launch — a client-side region gate couldn't see a server-only configuration flag and was always hiding the tile. USA-region clicks now go to the hosted card checkout as designed.
  • improvedDocs — Webhooks page now includes a payment.failed mixed-checkout example alongside the existing payment.completed one. The correlation rules (payment_id / order_id always equal your root session ID) apply identically to both event types, regardless of which rail succeeded or failed.
May 8, 2026v1.16
  • newCard Payments — United States is now supported. US billing addresses route automatically through a hosted card checkout page (US billing is hosted-page only, no inline form). Customers click the same "Pay with Card" tile on /pay; if their region selector is set to USA they're taken to the hosted card page to enter card details. No merchant action needed — works automatically once the customer's region is USA. Same fees, same $7 minimum, same payouts as the EU/global flow.
  • newWebhooks — every payload now includes an order_id field as an explicit alias of payment_id. Both fields contain the merchant's root session ID (the value returned by POST /v1/payments). This makes the correct lookup pattern obvious in handler code (lookupOrder(payload.order_id)) and helps avoid a class of silent-fulfilment bugs where merchants accidentally key off the top-level id field — which, on mixed-checkout flows where the customer switches payment methods, is an internal child ID the merchant has never seen. Backward compatible: payment_id is unchanged.
  • improvedCard Payments — minimum order amount is now $7 USD, enforced platform-wide. Sub-$7 card attempts were being rejected upstream with no clear customer message; the card tile now hides for sub-$7 sessions on /pay, and direct API calls to POST /v1/payments with currency:"USD" + amount<7 + provider routing to card return AMOUNT_BELOW_MINIMUM (HTTP 422) up-front. Use crypto, regional methods, or Telegram Stars for sub-$7 orders.
  • improvedDocs — Webhooks page has a new prominent callout explaining order_id vs payment_id vs id, with side-by-side wrong / correct handler code examples and a real mixed-checkout payload sample (showing the parent / child relationship explicitly). Common silent-failure mode (merchant looks up by id, doesn't find anything, returns 200 OK without crediting) is now flagged front-and-centre.
May 8, 2026v1.15
  • fixOutgoing webhooks — the amount field is now consistently a string across every event and emitter (e.g. "24.99"), matching the docs and the rest of the API. Previously some paths shipped it as a raw JSON number, which broke strict-typed integrations that expected a string. If you were tolerating both, no change is needed; if you parsed it as a number, switch to parsing the string.
  • newDocs — Webhooks page now documents HMAC-SHA256 signature verification (X-Vexutopia-Signature header, t=…,v1=… format, signing string, and a 5-minute replay window) plus Node.js and Python verification snippets.
  • newDocs — Webhooks page now documents endpoint management: GET /v1/webhooks (list), GET /v1/webhooks/{id} (retrieve), and DELETE /v1/webhooks/{id} (delete, returns 204). DELETE was already supported but previously undocumented.
May 8, 2026v1.14
  • newIdempotency-Key support on POST /v1/payments — send a unique key per logical payment intent to make retries safe. Same key + identical body within 24 hours returns the original response (with header Idempotent-Replayed: true) instead of creating a second session; same key + different body returns 409 IDEMPOTENCY_KEY_REUSED. Opt-in and fully backward compatible — requests without the header behave exactly as before. See Docs → Payments → Idempotency.
  • newDocs — new section explaining the regional-payment correlation pattern for PIX / C2C / SBP. When a customer pays via a regional rail, the original transaction we returned from POST /v1/payments is moved to CANCELLED ("Superseded by [rail] regional payment") and the payment.completed webhook fires against a child transaction with its own ID. Always correlate by the webhook's payment_id field, which echoes the original ID we returned to you.
  • fixInvite acceptance page (vexutopia.com/invite/...) crashed with "Application error: a client-side exception has occurred" on every load — the page was using the Next.js 15 async-params API on a Next.js 14 codebase. Invite links now work end-to-end.
May 6, 2026v1.13
  • newPer-method on/off toggles in the sidebar Account panel — turn any approved payment method off (PIX/C2C/SBP, Open Banking, Card Payments, Alipay/WeChat, Crypto On-Ramp, Crypto) and customers stop seeing it on checkout. All default to on; toggles are only interactive once the underlying approval/wallet is in place. The change applies everywhere — hosted checkout, the Payments API, and dashboard charts/tabs.
May 6, 2026v1.12
  • newChina Pay — Alipay and WeChat Pay rails for customers paying in CNY (¥). Native QR + open-in-app deeplink checkout, treasury-settled to your merchant balance like PIX/C2C/SBP. Alipay 12% all-in, WeChat 13% all-in. Closed-loop wallets — no chargebacks. Per-Site approval gating (request access from Settings → Payment Methods).
  • newMonthly invoices — Vexutopia now issues a sequential PDF statement (VEX-2026-0001…) on the 1st of each month covering the prior month's revenue and platform fees, broken down per payment method. View and download from Dashboard → Invoices. Fill in your billing details under Settings → Billing — without them no invoice is issued.
  • improvedPIX (Brazil) and SBP (Russia) — checkout pages are now fully native on vexutopia.com. Your customers no longer see any third-party branding or hostname during the payment flow, mobile loads are faster, and the entire flow works in markets where the previous upstream domain was blocked or filtered.
  • improvedCard Payments fee schedule updated (see Pricing for the rates). Failed/declined attempts are not charged.
  • improvedCard Payments — the previous $6 minimum order amount has been removed. Small-ticket card orders ($1–$5.99 range) now go through. Refund and chargeback fees still apply per the schedule above.
  • improvedCard Payments — non-Latin customer names (Korean, Cyrillic, Chinese, Japanese, Arabic, etc.) are now automatically romanized before being sent to the card processor. Previously, orders with such names silently failed at the processor's name-validation step. No merchant action needed.
  • improvedCheckout — the "no payment methods available" screen now explains the specific reason (e.g. "Card payments unavailable in your country — try switching region") instead of a generic "please contact the merchant" message.
  • improvedSite URLs are now exclusive — once a merchant has claimed a domain in their Sites list, no other merchant account can register the same domain. Closes a domain-impersonation gap.
  • fixMobile checkout — regional payments (PIX, C2C, SBP, Open Banking, Alipay, WeChat) now open in the same tab on mobile instead of attempting a popup that mobile browsers block. Customers were previously stuck on a "complete payment in the new tab" interstitial that never advanced.
  • fixA US-only on-ramp option is now hidden at checkout for customers whose IP address isn't in the United States. Non-US clicks on it were always failing — they now don't see the option at all.
  • fixWhen a payment request is rejected (e.g. a region-restricted option, or an amount below the minimum), customers now see a styled error page with the actual reason instead of being silently bounced to the Vexutopia homepage.
May 5, 2026v1.11
  • newDashboard → Blocked emails — block specific customer email addresses from opening hosted checkout or completing a payment (organization-wide). Applies when an email is known on POST /v1/payments, on checkout session load if the merchant already supplied one, and when the customer enters email on card or regional flows. Blocked customers receive a clear message with code `CUSTOMER_BLOCKED`.
May 3, 2026v1.10
  • newCrypto (direct) — customers pay in cryptocurrency (BTC, ETH, stablecoins, and many other assets). Enabled from your backend with `crypto: true` on POST /v1/payments. The customer completes checkout on a dedicated vexutopia.com page (`/pay/crypto/<id>`), not the multi-method hosted checkout. Minimum invoice: USD 3 equivalent. Fees: a percentage of the invoice, shown on your fee schedule (e.g. 3%). Underpayments within 5% of the quoted amount still complete. Webhooks set `payment_method` to `crypto`.
  • improvedCrypto (direct) pricing updated, replacing the earlier flat 5.5% rate. The dashboard fee table shows your live rate.
  • improvedDashboard: a Bitcoin icon appears next to the Crypto tab in the payment history filter (alongside regional flags for PIX, C2C, SBP, and Open Banking)
  • fixReturn URLs that include `{status}` are now expanded to the actual status (success, fail, cancelled, or expired) on all hosted rails — the literal `{status}` token could previously leak into the browser address bar
May 1, 2026v1.9
  • newSettings → Payment Methods is now a dedicated tab — Card Payments, Telegram Stars, and Regional Payments (PIX/C2C/SBP/Open Banking) controls live in one place, separate from Payouts (which is now just your USDC payout wallet)
  • newPer-method toggles for regional payments — once a Site is approved, you can switch individual methods on/off (e.g. accept PIX and C2C but hide Open Banking) without losing approval status. Defaults to all methods on
  • newDirect Payments API — pass `direct: true` on POST /v1/payments to skip the Vexutopia checkout interstitial. The returned `checkout_url` is a hosted-checkout page on vexutopia.com that drops the customer straight onto the rail. Currently supported for PIX (BRL), C2C (ARS), and SBP (RUB). See /docs/direct-payments
April 28, 2026v1.8
  • newOpen Banking (EU) — direct bank-transfer rail for European customers paying in EUR. 11% all-in + EUR 1 per transaction. Auto-surfaced at checkout for customers in the EU SEPA zone
  • newSBP (Russia) — Faster Payments System QR rail for Russian customers paying in RUB. 15% all-in, 10–150,000 RUB per order, T+1 settlement. Auto-surfaced at checkout for customers in Russia
  • newDashboard Balances revamp — rolling reserve broken down by payment method, pending Stars + chargeback fees surfaced, recent payouts list, USD-equivalent on every card, and a "Withdraw all" CTA that bundles every non-Stars currency into one batch payout to a single crypto destination
  • newWithdrawals are now gated by per-rail settlement timing — Card Payments and Open Banking earnings show as "Maturing" until the T+7 window passes, SBP earnings until T+1. Funds become withdrawable once their settlement window has passed
  • newDashboard Balances now tracks EUR alongside BRL/ARS/RUB/XTR. Withdraw via the existing payout request flow
  • newPer-merchant approval gate for regional payments (PIX/C2C/SBP/Open Banking) — request access from the dashboard once your website is set; admin approves after your store has been reviewed
  • improvedAffiliate partners now earn on every rail (Card Payments, PIX, C2C, SBP, Telegram Stars, and Open Banking) — earnings were previously accruing only on the Crypto On-Ramp rail
April 27, 2026v1.7
  • newEmbedded Checkout — drop a Vexutopia card form straight into your own site via a one-line script tag. Customers complete payment without leaving your domain; card data still never touches your server. See /docs/embed for the snippet
  • newPer-site allow-list controls which of your domains can iframe the embedded checkout — set after KYC of that specific website, enforced via per-session frame-ancestors CSP
  • newpostMessage events (vexutopia:ready/resize/success/fail/cancel/expired) for the embedded iframe so your page knows what's happening without polling
  • newDashboard → Payouts & Wallets: "Card Payments on checkout.vexutopia" toggle — turn off the Card Payments tile on the Vexutopia-hosted checkout page if you only accept cards via the embedded flow on your own site
  • improvedDashboard now treats Card Payments and Crypto On-Ramp as separate methods — historical card-direct transactions previously bucketed under Crypto On-Ramp have been reclassified, and the chart legend gets a new "Card Payments" entry (indigo) for merchants with card processing enabled
April 24, 2026v1.6
  • newWebhooks now carry payment_method and processor fields on every event so you can attribute fees to the right rail without parsing settled_via
  • newAPI: POST /v1/payments/lookup — batch payment lookup, up to 100 ids per request, returns status and rail attribution
  • improvedGET /v1/payments/:id now includes payment_method and processor fields
  • improvedFees now include the fixed per-transaction component on PIX (+1 BRL) and Card/crypto; previously-affected transactions continue to show historical amounts
  • fixMixed-checkout webhooks (customer starts on one rail and completes on another) now use the original payment id and carry your original metadata so the event reconciles cleanly on your side
  • fixTelegram Stars payments no longer appear duplicated in the dashboard; the superseded card session is hidden from counts, charts, and success-rate math
  • fixDashboard payments list no longer hides non-superseded transactions due to a null-handling bug in the supersede filter
April 24, 2026v1.5
  • newDashboard overview: per-payment-method breakdown cards — volume and transaction count for each method (Crypto On-Ramp, Telegram Stars, PIX, C2C) shown side-by-side, with click-through to filtered history
  • newDashboard: transaction-volume chart redesigned as a stacked bar chart split by payment method, with per-method tooltip breakdown and legend
  • newPayments table: filter by payment method via a tab strip above the list; each tab deep-links with a ?method=… URL param
  • improvedPayment methods now carry distinct colours and country flags in the dashboard (🇧🇷 next to PIX, 🇦🇷 next to C2C) for faster scanning
  • improvedThe card/crypto method is now labelled "Crypto On-Ramp" across the dashboard to better reflect what merchants actually receive
  • improvedPayments table defaults to the Completed status filter so merchants see settled payments first
  • improvedTelegram Stars is hidden from the dashboard for merchants who haven't enabled it in Settings; flipping the toggle unhides it everywhere
  • fixFee and net-payout columns are now correctly expressed in USD for non-USD payments (BRL, ARS, EUR, JPY, XTR); previously-affected transactions were recalculated
April 2026v1.4
  • newRegional payments: PIX (Brazil) and card-to-card (Argentina) are now offered at checkout when the customer selects a matching region
  • newDashboard: Balances page shows available funds per currency for rails where Vexutopia settles to your account first
  • newDashboard: request payouts directly from the Balances page; status and history tracked per request
  • newAdmin: Payouts queue with REQUESTED → PROCESSING → COMPLETED flow, rejection reasons, and optional USDC settlement metadata
  • newAPI: Argentine peso (ARS) added to supported currencies on POST /v1/payments
  • improvedTransactions now record the fee and merchant-net amount for full settlement transparency
April 2026v1.3
  • newAffiliate partner program: earn a share of revenue from merchants you refer — apply at /affiliates
  • newAdmin: partner management, earnings ledger, payout tracking, and application review
  • newDashboard: Affiliate tab for partners to track referred merchants, earnings, and payouts
  • newAPI: optional country field on POST /v1/payments now also pre-selects the customer's region at checkout
  • improvedCheckout region selector: uses merchant-provided country hint when available, falls back to IP geolocation
April 2026v1.2
  • newDashboard: real-time stats and transaction volume chart with 7D/30D toggle
  • newDashboard: payments table with live data, filtering, and CSV export
  • newAPI: GET /v1/payments/:id — retrieve payment status
  • newWallet snapshot recorded per transaction for full payout auditability
  • fixLive API keys now blocked until a payout wallet is configured
  • fixInternal processing metadata no longer exposed in API responses
  • fixAlready-completed payments show green success screen on checkout
March 2026v1.1
  • newCheckout page redesign with provider selector and location-based routing
  • newGeo-based filtering of on-ramp options by customer country
  • newTrust badges and improved checkout UX
  • fixWebhook: ETH and non-USDC coins now correctly converted to USD
  • fix50% tolerance threshold prevents false failures on provider fee variations
January 2026v1.0
  • newPlatform launch: payment orchestration layer live
  • newMerchant dashboard with API key management
  • newOrganisation settings, team management, payout wallet configuration
  • newWebhook delivery with automatic retries
  • newAPI documentation at /docs