Payments
This guide covers the complete payment flow in ToffeePay, from creating payment sessions to handling confirmations.
Payment Flow
Create a Payment Session
Send a server-side request to create a payment session.
POST /pay.v1.PaymentService/CreateSession
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"game_id": "space_shooter",
"user_id": "player_42",
"item": {
"title": "50 Gold Coins",
"price": 499,
"currency": "USD",
"image": "data:image/png;base64,..."
},
"return_url": "mygame://payment-complete"
}
Parameters:
game_id
: Your unique game identifieruser_id
: Unique identifier for the playeritem
: The item being purchasedtitle
: Display name of the itemprice
: Price in cents (e.g., 499 = $4.99)currency
: Three-letter currency code (USD, EUR, etc.)image
: Base64-encoded image or URL
return_url
: Deep link to return to after payment
Response
{
"id": "sess_abc123",
"url": "https://pay.toffeepay.com/sess_abc123"
}
Payment Statuses
Session Statuses
Payment sessions can have the following statuses:
pending
: Payment session created but not yet paidpaid
: Payment successfully completedfailed
: Payment attempt failedcancelled
: Payment was cancelled by the userexpired
: Payment session has expired
Payment Statuses
Individual payment objects (created when processing a session) have these statuses:
processing
: Payment is being processed by the payment providersucceeded
: Payment completed successfullyfailed
: Payment processing failed
Status Flow:
- Session starts as
pending
- When payment begins, a Payment object is created with status
processing
- Payment resolves to either
succeeded
orfailed
- Session status updates to
paid
(if payment succeeded) orfailed
(if payment failed)
Timestamp Fields
Both sessions and payments include relevant timestamp fields:
Session timestamps:
created_at
: When the session was createdpaid_at
: When the session was successfully paid (if applicable)failed_at
: When the session failed (if applicable)cancelled_at
: When the session was cancelled (if applicable)
Payment timestamps:
created_at
: When payment processing begansucceeded_at
: When payment completed successfully (if applicable)failed_at
: When payment failed (if applicable)
Webhook Events
ToffeePay sends webhooks for the following payment-related events:
Session Events
session.created
: When a payment session is createdsession.paid
: When a session is successfully paidsession.failed
: When payment attempt related to this session failssession.expired
: When a session expires without paymentsession.cancelled
: When session is cancelled by user
Payment Events
payment.created
: When a payment is created and processing beginspayment.succeeded
: When payment completes successfullypayment.failed
: When payment attempt fails
See the Webhooks page for implementation details and signature verification.
Open the Payment Page
Open the returned payment_url
in the browser or webview.
The user will:
- View the item details and total price
- Pay using Apple Pay, Google Pay, or other supported methods
- Be redirected back to your game via the
return_url
Handle Payment Notifications
ToffeePay notifies you of payment events through two methods:
1. Webhooks
When a payment is completed, ToffeePay sends a signed webhook to your backend. See the Webhooks page for detailed implementation.
Sample Payload:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"event": "payment.succeeded",
"timestamp": "2023-06-01T12:05:00Z",
"data": {
"payment_id": "pay_xyz789"
}
}
2. Return URL
After payment, the user is redirected to your specified return_url
. This is typically a custom deep link that your game handles.
Example:
"return_url": "mygame://payment-complete"
Cancel a Payment Session
You can cancel a payment session that is still in pending
status:
POST /pay.v1.PaymentService/CancelSession
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"id": "sess_abc123"
}
Response:
{}
When a session is cancelled:
- The session status changes to
cancelled
- The
cancelled_at
timestamp is set - A
session.cancelled
webhook event is sent - The session cannot be paid and the payment URL becomes invalid
Check Session Status
To confirm session status (especially when handling return URLs), you can use either endpoint:
GetSession (Full Details)
POST /pay.v1.PaymentService/GetSession
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"id": "sess_abc123"
}
Response:
{
"id": "sess_abc123",
"status": "paid",
"payment_id": "pay_xyz789",
"user_id": "player_42",
"game_id": "space_shooter",
"item": {
"title": "50 Gold Coins",
"price": 499,
"currency": "USD"
},
"created_at": "2023-06-01T12:00:00Z",
"paid_at": "2023-06-01T12:05:00Z"
}
GetSessionStatus (Status Only)
POST /pay.v1.PaymentService/GetSessionStatus
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"id": "sess_abc123"
}
Response:
{
"id": "sess_abc123",
"status": "paid"
}
Status handling:
- If
status
ispaid
, grant the items and show success - If
status
ispending
, show a waiting screen - If
status
isfailed
,cancelled
orexpired
, inform the user and offer to retry
Get Payment Details
Retrieve details of a payment:
POST /pay.v1.PaymentService/GetPayment
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"id": "pay_xyz789"
}
Response:
{
"id": "pay_xyz789",
"session_id": "sess_abc123",
"status": "succeeded",
"amount": 499,
"currency": "USD",
"method": "apple_pay",
"details": "50 Gold Coins",
"created_at": "2023-06-01T12:05:00Z",
"succeeded_at": "2023-06-01T12:05:30Z"
}
List Sessions
Retrieve historical sessions for audit and analytics:
POST /pay.v1.PaymentService/ListSessions
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"game_id": "space_shooter",
"user_id": "player_42",
"status": "paid",
"limit": 50,
"offset": 0
}
Response:
{
"sessions": [
{
"id": "sess_abc123",
"status": "paid",
"payment_id": "pay_xyz789",
"user_id": "player_42",
"game_id": "space_shooter",
"item": {
"title": "50 Gold Coins",
"price": 499,
"currency": "USD"
},
"created_at": "2023-06-01T12:00:00Z",
"paid_at": "2023-06-01T12:05:00Z"
}
],
"total": 1,
"has_more": false
}
List Payments
Retrieve historical payments (successful transactions only):
POST /pay.v1.PaymentService/ListPayments
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"game_id": "space_shooter",
"user_id": "player_42",
"limit": 50,
"offset": 0
}
Response:
{
"payments": [
{
"id": "pay_xyz789",
"session_id": "sess_abc123",
"status": "succeeded",
"amount": 499,
"currency": "USD",
"method": "apple_pay",
"details": "50 Gold Coins",
"created_at": "2023-06-01T12:05:00Z",
"succeeded_at": "2023-06-01T12:05:30Z"
}
],
"total": 1,
"has_more": false
}
Image Requirements
Item images must meet these requirements:
- Format: PNG, JPG, WebP
- Size: ≤ 300 KB recommended
- Encoding: Base64 with MIME prefix or direct URL
Base64 format:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
URL format:
https://yourgame.com/images/gold-coins.png
Best Practices
- Authentication: See Authentication for API key management
- Idempotency: Use Idempotency-Key header to prevent duplicate operations
- Webhook verification: Always verify webhook signatures (see Webhooks)
- Error handling: Implement proper error handling for all payment statuses
- User experience: Show loading states and clear success/failure messages
- Security: Use HTTPS for all webhook endpoints and return URLs
- Testing: Use sandbox mode for development and testing
Error Handling
Common payment errors and how to handle them:
invalid_game_id
: Check your game registration and API key (see Authentication)invalid_currency
: Ensure currency code is supported (USD, EUR, etc.)invalid_price
: Price must be a positive integer in centsinvalid_image
: Check image format and size requirementssession_expired
: Payment session has expired, create a new oneinsufficient_funds
: User's payment method was declined
Testing
Use ToffeePay's sandbox environment for testing:
- Use sandbox API keys (different from production)
- Test with various payment methods and failure scenarios
- Verify webhook delivery and signature verification
- Test return URL handling in your game client