AccelByte Blog: Insights on Game Development & Backend

Open Source Regional Payment Gateway for Games: built on AccelByte Extend

Written by AccelByte Inc | May 14, 2026 2:56:30 PM

We just released a regional payment gateway as part of AccelByte Extend, an open-source service extension that connects your game economy to regional payment providers like Xendit and KOMOJU. It handles the full lifecycle: intent creation, webhook processing, item fulfillment, refunds, and cancellation.

If you're shipping on your own launcher in Southeast Asia or Japan, this is probably relevant to you. If you're already on AccelByte Gaming Services, it plugs directly into your existing economy setup. And if you're using a different backend entirely, the payment logic itself (adapters, state machine, webhook handling) is independent enough that you can fork it and swap in your own fulfillment layer.

A quick bit of context

AccelByte Gaming Services (AGS) is a modular backend platform for game studios covering identity, matchmaking, economy, cloud save, leaderboards, and more. Studios use it to skip building and operating those systems themselves so they can focus on the game.

AccelByte Extend is the customization layer on top of AGS. It lets studios write their own backend logic, whether that's new services, event handlers, or overrides to AGS defaults, and deploy it without worrying about hosting or infrastructure. The scaffolding for auth, observability, and deployment is already there. You write the logic that makes your game unique.

This payment gateway is an Extend Service Extension: a new service your game can call directly, hosted by AccelByte, talking to your payment providers on one side and your AGS economy on the other.

Why regional payment methods are a real problem

If you're shipping on Steam or the Epic Games Store, payment localization is largely handled for you. Those platforms know their markets.

If you're shipping on your own launcher, you own the payment stack. And that means you need to support how players in your target regions actually pay.

In Indonesia alone, around 39% of gaming payments go through e-wallets like GoPay, OVO, and DANA, while 27% go through bank transfers. Cards are the minority. Japan is in a different situation: konbini (convenience store) payments and Pay-easy ATM transfers are common, where a player completes a digital purchase at a 7-Eleven counter and uses a code to unlock their content.

AGS ships with built-in support for payment providers like Stripe, Xsolla, Adyen, and Checkout.com. Those work well for most Western markets. For ASEAN and Japan, you need something else, and before this extension you mostly build it yourself.

What makes regional payment integration genuinely tricky

The tempting approach is a single abstraction that normalizes all payment providers. In practice it doesn't hold up, because each provider has its own rules for everything:

  • Webhook signature validation — Xendit uses a token in the request header; KOMOJU uses HMAC-SHA256 with a shared secret. The validation logic for one doesn't apply to the other.
  • Checkout flow — some providers return a hosted URL to redirect the player to; others return a payment code for a physical location.
  • Cancellation — some providers let you cancel programmatically via API, others only expire naturally. Handling both gracefully matters.
  • Refunds — partial refund support varies by provider, and sometimes by payment method within the same provider.
  • Sandbox certification — some providers require you to run a defined set of test cases and get approval before going live, a step that doesn't exist with most Western gateways.

The extension handles all of this without leaking provider-specific behavior into the rest of your application.

What makes regional payment integration genuinely tricky

The core flow runs across two phases:

  • In the first, your game client sends a payment intent to the gateway, which creates a PENDING transaction, calls the provider to generate a checkout URL, and returns it to the player.
  • In the second phase, the provider posts a webhook back once payment is complete. The gateway validates the signature, updates the transaction to FULFILLING, calls AGS to fulfill the item, and marks it FULFILLED.

Beyond the happy path, the service handles a few things that come up in production:

  • Dropped webhooks — a background scheduler polls for stuck PENDING transactions and reconciles them against the provider's status API.
  • Duplicate delivery — the FULFILLING state acts as a claim. Once claimed, duplicate webhooks for the same transaction are discarded.
  • Replay attacks — webhooks older than a configurable threshold (default: 5 minutes) are rejected before any state change.
  • Mid-flow cancellation — if a player exits before paying and the provider supports it, the service cancels the transaction immediately.

The adapter pattern

Every payment provider implements a single Go interface:

Go
type PaymentProvider interface {

Info() ProviderInfo

ValidatePaymentInit(req PaymentInitRequest) error

CreatePaymentIntent(ctx context.Context, req PaymentInitRequest) (*PaymentIntent, error)

GetPaymentStatus(ctx context.Context, providerTxID string) (*ProviderPaymentStatus, error)

SyncTransactionStatus(ctx context.Context, tx *model.Transaction) (*ProviderSyncResult, error)

ValidateWebhookSignature(ctx context.Context, rawBody []byte, headers map[string]string) error

HandleWebhook(ctx context.Context, rawBody []byte, headers map[string]string) (*PaymentResult, error)

RefundPayment(ctx context.Context, internalOrderID string, providerTxID string, amount int64, currencyCode string) error

CancelPayment(ctx context.Context, tx *model.Transaction, reason string) (*CancelResult, error)

ValidateCredentials(ctx context.Context) error

}

Adding a new provider means creating a package under internal/adapter/{vendor}/ and implementing these methods. Everything else, the checkout handler, webhook router, fulfillment logic, scheduler, and admin endpoints, stays untouched.

The extension ships with Xendit and KOMOJU because that's where we focused first, but the interface is region-agnostic and provider-agnostic. There's also a Generic HTTP adapter for providers that follow standard redirect-and-webhook flows, configurable entirely through GENERIC_{NAME}_* environment variables with no code changes. So while this was built with Southeast Asia and Japan in mind, it can be adapted to any payment provider in any region.

The engineer who built this, Nauval Muhammad Firdaus, used the Extend Service Extension template and the provider API docs as his two inputs. The initial working version took a few hours. The template already had auth, observability, and the deployment pipeline in place. What he wrote was the payment logic itself.

What's included

The repo is at github and is part of the AccelByte Extend Apps Directory, an open-source collection of Extend apps for common patterns studios build on top of AGS. Out of the box it ships with:

  • Xendit — ASEAN markets, multi-currency, hosted checkout via Xendit Payment Sessions. Supports regional allowlists to control which providers appear where.
  • KOMOJU — Japan, South Korea, China, and parts of Europe. Hosted checkout via KOMOJU Sessions API with HMAC-SHA256 webhook validation.
  • Generic HTTP adapter — zero code, env-var-driven. For any provider that follows standard redirect-and-webhook conventions.

Each adapter has its own guide in docs/adapter/ covering credentials, sandbox setup, and certification test cases where required.

Get started for free

AccelByte Gaming Services is free during development and comes with all the core backend services you need to build and test your game, including access to AccelByte Extend. That means you can run this payment gateway locally, configure your provider sandbox accounts, and have the full stack working before you pay anything.

Sign up for free

If you to walk through how this fits your stack, talk to us.