Integrating Stash Pay
Stash Pay is a direct-to-consumer payment system for games and apps.
This guide shows how to integrate it with the minimum setup, whether for a webshop or in-app purchases.
The video below walks you through the process.
Before you start
Before integrating Stash Pay, make sure you have:
- Access to Stash Studio, our developer portal.
- An API key created in Stash Studio.
- A webshop or game client where you want to trigger purchases.
Create a checkout link
Send a POST request to the /sdk/checkout_links/create
endpoint from your backend to start a Stash Pay purchase.
Include your API key in the request header as X-Stash-Api-Key: YOUR_API_KEY
.
Make sure this call is made from your server to keep your API key secure.
Checkout link request
Here’s a sample payload for creating a checkout link:
{
"user": {
"id": "user_12345",
"validatedEmail": "player@example.com",
"displayName": "Player123",
"avatarIconUrl": "https://example.com/avatar.png",
"profileUrl": "https://example.com/profile"
},
"shopHandle": "YOUR_INSTANCE_HANDLE",
"currency": "USD",
"items": [
{
"id": "battle_pass_001",
"pricePerItem": "499",
"quantity": 1,
"imageUrl": "https://cdn.example.com/images/battle_pass.png",
"name": "Battle Pass",
"description": "Access to premium season content"
}
]
}
Parameter | Content | Type |
---|---|---|
shopHandle | The name of your shop. You can find this value in the Details section of Stash Studio. | string |
currency | The ISO 3166-1 currency code to use for the payment. | string |
user | An object containing information about the player that initiated the purchase. | object |
items | An array of items included in the purchase. | array[object] |
Checkout link response
If the request succeeds, send the url or id to your game client to present the checkout to the user.
{
"url": "https://store.example.com/order/abc123",
"id": "abc123"
}
Displaying the checkout
You can display the checkout in a browser or in-app. Choose the option that works best for your integration.
Browser Purchase
Display the URL on the user’s device.
window.open(stash_pay_url, '_blank');
Example in Unity using Application.OpenURL
.
public class CheckoutHandler : MonoBehaviour
{
public void OpenCheckoutURL(string stash_pay_url)
{
Application.OpenURL(stash_pay_url);
}
}
In-App purchase
Use this option for in-app purchases. See Apple iOS Integration section for presentation options and how Stash Pay communicates with your game client.
Handle Webhook Events
After a purchase is completed, Stash sends webhook notifications to your backend to confirm the transaction. This webhook-based messaging system ensures reliable communication between Stash and your game server, allowing you to grant items to players only after payment is confirmed.
How Stash Messaging Works
Stash uses a failsafe purchase flow that prevents disputes and ensures players are only charged once fulfillment is complete:
- Pre-authorization: Stash pre-authorizes the payment and holds funds
- Webhook Notification: Your server receives a
PURCHASE_SUCCEEDED
webhook - Item Granting: Your server grants items to the player
- Confirmation: Your server responds to confirm fulfillment
- Finalization: Stash finalizes the charge only after confirmation
This process ensures that players are never charged for items they don’t receive due to technical issues.
Webhook Setup and Implementation
To handle webhook events, you need to:
- Configure webhooks in Stash Studio (Settings → Webhooks)
- Create a webhook listener on your backend to receive notifications
- Verify webhook signatures for security
- Process the webhook payload and grant items to players
For complete webhook implementation details, see our Webhooks Overview and Webhook List documentation.
Webhook Payload Example
{
"type": "PURCHASE_SUCCEEDED",
"purchaseSucceeded": {
"timeMillis": 1753993257000,
"orderId": "8ZVBabLrnCMm9zPdu9QpfCWzNaA",
"currency": "usd",
"userId": "user_12345",
"items": [
{
"id": "battle_pass_001",
"quantity": 1,
"price": "499"
}
],
"tax": "0",
"total": "499",
"regionCode": "US",
"source": "StashPay"
}
}
Expected Response
Always respond with HTTP 200 OK
to confirm that the purchase was processed on your side, such as granting users the item. Ensure this response is sent only after you’ve successfully granted the items to the player. This approach prevents duplicate fulfillment and guarantees accurate payment capture.