Register in-game payment records. Registered payments are automatically attributed to the user’s boosted creator.
Flow
1. In-game payment complete → 2. Send payment info via API → 3. Creator attribution + settlement
Create Payment
Request
curl -X POST "https://sandbox-sdk-api.playcamp.io/v1/server/payments" \
-H "Authorization: Bearer ak_server_xxx:secret" \
-H "Content-Type: application/json" \
-d '{
"userId": "user_12345",
"transactionId": "txn_abc123",
"productId": "gem_pack_100",
"productName": "100 Gem Pack",
"amount": 9900,
"currency": "KRW",
"platform": "Android",
"distributionType": "MOBILE_STORE",
"purchasedAt": "2024-01-15T10:30:00.000Z"
}'
const payment = await server.payments.create({
userId: 'user_12345',
transactionId: 'txn_abc123',
productId: 'gem_pack_100',
productName: '100 Gem Pack',
amount: 9900,
currency: 'KRW',
platform: 'Android',
distributionType: 'MOBILE_STORE',
purchasedAt: new Date('2024-01-15T10:30:00Z'),
});
purchasedAt, _ := time.Parse(time.RFC3339, "2024-01-15T10:30:00Z")
payment, err := server.Payments.Create(ctx, playcamp.CreatePaymentParams{
UserID: "user_12345",
TransactionID: "txn_abc123",
ProductID: "gem_pack_100",
ProductName: playcamp.String("100 Gem Pack"),
Amount: 9900,
Currency: "KRW",
Platform: playcamp.PaymentPlatformAndroid,
DistributionType: playcamp.String("MOBILE_STORE"),
PurchasedAt: purchasedAt,
})
Response (201 Created)
{
"data": {
"id": 1234,
"transactionId": "txn_abc123",
"userId": "user_12345",
"productId": "gem_pack_100",
"productName": "100 Gem Pack",
"amount": 9900,
"currency": "KRW",
"platform": "Android",
"campaignId": "campaign_001",
"creatorKey": "ABC12",
"status": "COMPLETED",
"purchasedAt": "2024-01-15T10:30:00.000Z",
"createdAt": "2024-01-15T10:30:05.000Z"
}
}
Required Parameters
| Field | Type | Description |
|---|
userId | string | In-game user identifier |
transactionId | string | Platform-specific unique transaction ID (for deduplication) |
productId | string | Product ID |
amount | number | Payment amount |
currency | string | Currency code (ISO 4217: USD, KRW recommended) |
platform | string | Platform (iOS, Android, Web, Roblox, Other) |
distributionType | string | Distribution type (see below) |
purchasedAt | string | Actual payment timestamp (ISO 8601) |
Optional Parameters
| Field | Type | Description |
|---|
productName | string | Product name |
callbackId | string | Webhook tracking ID (included in webhook events) |
isTest | boolean | Test mode (does not create actual data) |
Distribution Type (Required)
distributionType is a required parameter when registering payments. It’s used for settlement calculation.
| Value | Description | Store Fee |
|---|
MOBILE_STORE | Mobile external store (Google Play, App Store) | 30% |
PC_STORE | PC external store (Steam, etc.) | 30% |
MOBILE_SELF_STORE | Mobile self-payment | 0% |
PC_SELF_STORE | PC self-published store | 0% |
Settlement Calculation: Net Amount = Payment Amount × (1 - Store Fee), then PlayCamp platform fee and creator fee are applied separately.Important: Specify the value matching the actual distribution channel where the payment occurred for accurate settlement.
Currency Conversion
For non-USD currencies, amount is automatically converted to USD (amountUsd field).
// KRW payment example
{ amount: 9900, currency: "KRW" }
// → amountUsd: 7.62 (auto-calculated)
Refund Payment
curl -X POST "https://sandbox-sdk-api.playcamp.io/v1/server/payments/txn_abc123/refund" \
-H "Authorization: Bearer ak_server_xxx:secret" \
-H "Content-Type: application/json" \
-d '{}'
const refund = await server.payments.refund('txn_abc123');
payment, err := server.Payments.Refund(ctx, "txn_abc123", nil)
Refunded amounts are deducted from settlement.
Error Handling
| HTTP | Code | Description |
|---|
| 400 | VALIDATION_ERROR | Missing required parameter |
| 409 | CONFLICT | Duplicate transactionId |
Bulk Payment
Register up to 1,000 payments at once.
Request
curl -X POST "https://sandbox-sdk-api.playcamp.io/v1/server/payments/bulk" \
-H "Authorization: Bearer ak_server_xxx:secret" \
-H "Content-Type: application/json" \
-d '{
"payments": [
{
"userId": "user_1",
"transactionId": "txn_001",
"productId": "gem_pack_100",
"amount": 9900,
"currency": "KRW",
"platform": "iOS",
"distributionType": "MOBILE_STORE",
"purchasedAt": "2026-03-17T00:00:00Z"
},
{
"userId": "user_2",
"transactionId": "txn_002",
"productId": "gem_pack_200",
"amount": 19900,
"currency": "KRW",
"platform": "Android",
"distributionType": "MOBILE_STORE",
"purchasedAt": "2026-03-17T00:00:00Z"
}
],
"callbackId": "bulk-001"
}'
const result = await server.payments.createBulk({
payments: [
{
userId: 'user_1',
transactionId: 'txn_001',
productId: 'gem_pack_100',
amount: 9900,
currency: 'KRW',
platform: 'iOS',
distributionType: 'MOBILE_STORE',
purchasedAt: '2026-03-17T00:00:00Z',
},
{
userId: 'user_2',
transactionId: 'txn_002',
productId: 'gem_pack_200',
amount: 19900,
currency: 'KRW',
platform: 'Android',
distributionType: 'MOBILE_STORE',
purchasedAt: '2026-03-17T00:00:00Z',
},
],
callbackId: 'bulk-001', // optional
});
console.log(result.totalRequested); // 2
console.log(result.successful); // successful count
console.log(result.failed); // failed count
console.log(result.skipped); // skipped count
purchasedAt, _ := time.Parse(time.RFC3339, "2026-03-17T00:00:00Z")
result, err := server.Payments.CreateBulk(ctx, playcamp.CreateBulkPaymentParams{
Payments: []playcamp.CreatePaymentParams{
{
UserID: "user_1",
TransactionID: "txn_001",
ProductID: "gem_pack_100",
Amount: 9900,
Currency: "KRW",
Platform: playcamp.PaymentPlatformIOS,
DistributionType: playcamp.String("MOBILE_STORE"),
PurchasedAt: purchasedAt,
},
{
UserID: "user_2",
TransactionID: "txn_002",
ProductID: "gem_pack_200",
Amount: 19900,
Currency: "KRW",
Platform: playcamp.PaymentPlatformAndroid,
DistributionType: playcamp.String("MOBILE_STORE"),
PurchasedAt: purchasedAt,
},
},
CallbackID: "bulk-001", // optional
})
Response (200 OK)
{
"data": {
"totalRequested": 2,
"successful": 2,
"failed": 0,
"skipped": 0,
"results": [
{
"transactionId": "txn_001",
"status": "SUCCESS",
"data": { "id": 1234, "transactionId": "txn_001", "userId": "user_1" }
},
{
"transactionId": "txn_002",
"status": "SUCCESS",
"data": { "id": 1235, "transactionId": "txn_002", "userId": "user_2" }
}
]
}
}
Bulk Payment Parameters
| Field | Type | Description |
|---|
payments | array | Payment items array (max 1,000). Each item has the same required parameters as single payment |
callbackId | string | Webhook tracking ID (optional) |
isTest | boolean | Test mode (optional) |
Result Status
| Status | Description |
|---|
SUCCESS | Payment registered successfully |
SKIPPED | Already existing transactionId (duplicate) |
FAILED | Registration failed (validation error, etc.) |
Bulk payments support partial success. Even if some items fail, the remaining items are processed normally. A payment.bulk_created webhook event is triggered when the bulk payment completes.