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 reference 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"
}

Authentication

Authenticate calls to generate_quick_pay_url by signing the request body with your ingress secret and including the signature in the x-stash-hmac-signature header. Your ingress secret is distinct from the egress key used to verify Stash's outbound requests. Both are in Studio → Project Settings → API Keys as base64-encoded values; base64-decode before use as the HMAC key.

x-stash-hmac-signature: v1;<appId>;<unixMillisTimestamp>;<base64-hmac>
FieldDescription
v1Protocol version
<appId>Your immutable App ID (Studio → Project Settings → General)
<unixMillisTimestamp>Request timestamp in Unix milliseconds
<base64-hmac>Standard base64-encoded HMAC-SHA256 signature

The signature covers "<unixMillisTimestamp>." + <body>, where <body> is the exact JSON bytes you POST. Sign what you transmit — Stash verifies against the bytes received. Requests where <unixMillisTimestamp> is more than 5 minutes from the server clock are rejected.

For Node.js, Python, and Go implementation code, see API Keys → HMAC Signing.

Shops and API keys created before 2026-08-15 can still use X-Stash-Api-Key: <secret> instead. Keys created on or after 2026-08-15 must use versioned HMAC.

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.

The three differ mainly in when they fire relative to the charge, and only one of them lets your server reject a purchase:

PatternWhen it firesDirectionCan your server reject?Best for
ConfirmPaymentBefore the charge is capturedStash calls your serverYes. See the warning in that tab.Inventory limits, purchase caps, multi-client locking
PURCHASE_SUCCEEDED webhookAfter the payment completesStash calls your serverNoBackends that process events asynchronously through queues, workers, or jobs
GetPaymentEventAfter the payment completes, when you ask for itYour server calls StashNoShowing rewards in the client immediately after purchase

This is an integration-time choice, not a runtime one. Which delivery mechanism a shop uses is fixed when the shop is configured, not selected per purchase, so a single shop uses one of these patterns rather than switching between them. Pick the row that matches your backend, and see the High-Level Flow Options guide for the full sequence of each.

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:

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?

On this page