Integrating Stash Pay

Learn how to integrate Stash Pay into your game or app with minimum setup. This guide covers creating checkout links, displaying checkouts in browser or in-app, and handling webhook events for secure payment processing.

This guide explains how to integrate Stash Pay using the basic setup: creating checkout links, showing the checkout to players, and processing purchase events.

The video below provides a quick walkthrough of the integration flow.

Apple Pay and Google Pay do not work in the test environment without individual setup. Both require sandbox accounts. Contact your Stash representative to provision them for your test environment if needed.

To create a checkout session, send a POST request from your backend to the /sdk/server/checkout_links/generate_quick_pay_url endpoint. Please check out the full API refreence to see all the payload options.

Here's a sample payload for creating a checkout link:

{
  "item": {
    "id": "",
    "pricePerItem": "",
    "quantity": 1,
    "imageUrl": "",
    "name": "",
    "description": ""
  },
  "user": {
    "id": "",
    "validatedEmail": "",
    "profileImageUrl": "",
    "displayName": "",
    "regionCode": "",
    "platform": "UNDEFINED"
  },
  "transactionId": "",
  "regionCode": "",
  "currency": ""
}
ParameterTypeDescription
itemobjectThe item being purchased.
Fields:
- id: Unique identifier for the item.
- pricePerItem: Price per item in the smallest currency unit (e.g., cents).
- quantity: Number of items being purchased.
- imageUrl: Optional image representing the item.
- name: Name of the item.
- description: Short description of the item.
userobjectInformation about the purchasing user.
Fields:
- id: Unique user ID (from your system).
- validatedEmail: (optional) Email address if available and validated.
- profileImageUrl: (optional) Link to the user's avatar image.
- displayName: User display name.
- regionCode: (optional) User's region code for localization.
- platform: Platform string, e.g., IOS, ANDROID, or UNDEFINED.
transactionIdstringUnique transaction identifier generated by your backend for idempotency and tracking.
regionCodestring(optional) Region/country code for payment localization (e.g., "US").
currencystringISO 4217 currency code for the transaction (e.g., "USD", "EUR").

If your request succeeds, you will receive a checkout URL that you can present to the user using any of the methods described below.

Generate Checkout Response
{
  "url": "https://store.example.com/order/abc123",
  "id": "abc123",
  "regionCode": "US"
}

Displaying the checkout

The simplest option is to open the checkout URL directly in a browser on the user's device. For in-app presentation with native drawers, modals, and callbacks, follow the platform-specific integration guide for your stack.

Processing Purchase

Once a player completes checkout, your system must process the event to grant items. Stash supports three patterns depending on your game's requirements — always server-side, never on the client.

Choosing the right pattern: See the High-Level Flow Options guide to understand when to use each pattern based on your inventory management needs, granting behavior, and backend architecture.

Async post-purchase — Stash sends your backend a PURCHASE_SUCCEEDED webhook after the payment completes.

Best for: Backends that process events asynchronously (queues, workers, background jobs), where it's acceptable for rewards to appear a bit later in the game.

Configure your webhook endpoint in Stash Studio and implement a listener that verifies the signature and grants rewards. See the webhook guides for full implementation details:

Synchronous post-purchase — your backend polls Stash for the final payment status immediately after checkout.

With GetPaymentEvent, the client gets a definitive answer right after purchase without relying on incoming webhooks.

Best for: Games where the client needs rewards shown immediately after purchase, backends designed for synchronous request–response patterns, or when you prefer to avoid webhooks.

How it works:

  1. Player completes checkout
  2. Your backend calls GetPaymentEvent with the purchase ID
  3. Stash returns the final status of the payment
  4. If successful, your backend grants rewards and returns updated state to the client
Query Purchase Status
GET https://test-api.stash.gg/sdk/server/payment/<payment_id>

For complete endpoint documentation, see the GetPaymentEvent API Reference.

Pre-authorization validation — Stash calls your backend before finalizing the charge.

With ConfirmPayment, your game server can validate the purchase, optionally grant rewards, and then approve or reject the transaction before any money moves.

Best for: Games with per-player inventory limits, multi-client locking, or other validation that must happen before a purchase is finalized.

How it works:

  1. Player completes checkout
  2. Stash sends a ConfirmPayment request to your backend
  3. Your backend validates and optionally grants rewards
  4. Your backend responds with Approve or Reject
  5. Stash finalizes or cancels the charge accordingly

For implementation details including request validation and webhook signature verification, see the Webhook Listener guide. For the full request/response schema, see the ConfirmPayment API Reference.

Testing your integration

To test your Stash Pay integration, use test card numbers in the Stash test environment. These cards allow you to complete transactions safely, as no real charges are created, making repeated testing risk-free.

Environment Requirements:

  • Test/Development/Staging: Use test cards only. Test cards function in test environments and will be rejected in production.
  • Production: Use real, live payment cards only. Real cards are accepted for production transactions and will be rejected in test environments.
  • Apple Pay and Google Pay are not available in the test environment. These payment methods require live mode and will not function when testing.

Testing Tools

Link Generator: Use the Link Generator in Stash Studio to quickly generate and test checkout links without writing code. The Link Generator allows you to:

How is this guide?