Skip to content

Payment API

This page describes the Hive Axyl Server API that the app server calls directly for 'Payment'. It includes the receipt verification APIs, with which the app server rechecks payment receipts with the market, and the API that retrieves the purchase history for each payment provider.

Verify consumable product receipts

Server API

POST /payment/v1/purchase/verify

Rechecks the payment receipt of a consumable product with the official APIs of Apple App Store, Google Play, Steam, and PG. This step prevents products from being fraudulently delivered through forged or tampered receipts or requests without an actual payment; deliver products only when this verification passes. For Steam payments, the server checks the order with Steam and then proceeds with the actual charge while it processes this API, so the payment is confirmed at the time you call this API.

Receipt verification is requested only through this API. When the app client passes the receipt information to the app server after payment, the app server calls this API and delivers the product according to the verification result. For the implementation procedure for each payment provider, see Verify Apple consumable product receipts, Verify Google Play consumable product receipts, Verify Steam consumable product receipts, and Verify PG consumable product receipts.

Before calling the API

  • Caller: app server
  • Base URL
    • Production: https://commerce-api.hiveaxyl.com
    • Sandbox: https://sandbox-commerce-api.hiveaxyl.com
  • Authentication: Authorization: Bearer {access-token}
Warning

Put the token for the app server that you received from Issue a token in the authentication header. Keep the access token and the Client Secret used for token issuance only on the app server, and do not include them in the app client.

Call parameters

Name Location Type Required Description
X-App-Id header string true The App ID registered in the Hive Console.
X-SDK-Version header string false Client SDK version information.
X-Platform header string false Platform information.
X-OS-Version header string false Operating system version information.
Accept-Language header string false Client language setting.
traceparent header string false W3C Trace Context header for distributed tracing.
User-Agent header string false User-Agent information of the client application.
body body PurchaseVerifyRequest true Receipt verification request information.

Request body PurchaseVerifyRequest

Field Type Required Description
accountUuid string(uuid) true Value that links the logged-in user to this purchase record. Put the value the app client created in Generate an AccountUuid. It is used to check that the user who paid and the user who requested verification are the same, and it must be in UUID format.
appVersion string false App version. If omitted, the X-SDK-Version header value is saved. The app server does not send this header, so to record the app version, pass it in this field.
axylReceipt string true Purchase receipt. The value to put differs by market, so see Request values by market.
country string false Country code. Uses the ISO 3166-1 two-letter format.
currency string false Payment currency. Uses the ISO 4217 three-letter format. Paired with price, it is used to compare against the payment information the server has. If you send only one of the two, only the amount is compared, not the currency.
iapPayload string false Payload defined by the app. The value you send is saved as is and returned as hiveAxylPayload in the response.
language string false Language code. Uses the ISO 639-1 two-letter format.
orderId string false Order number. The server looks up the order using storeTransactionId, orderId, and axylReceipt, in that order.
price number false Payment amount. Includes decimals depending on the currency. If you send it, the server compares it with the payment amount it has; if you omit it, no comparison is made. How a different amount is handled differs by market. The payment history stores not this value but the amount the server confirmed from the market verification result or the order information.
productId string true In-app product ID registered in the market.
projectInfo object false Additional data that each app defines freely. It is only saved and is not returned in the response, so to get a value back in the response, use iapPayload.
providerId string true Market type. Specify one of APPLE, GOOGLE, STEAM, and PG.
requestType integer true Request type. 1 is a new purchase and 2 is purchase restoration; only these two values are allowed.
serverId string false Server ID registered in App Info > App Server of the Hive Console. For details, see App server.
storeTransactionId string false Store transaction ID. It is the first key used to look up the order.

Request values by market

The following fields take different values, or are processed differently by the server, depending on the market.

  • providerId: APPLE
  • axylReceipt: The original StoreKit 2 transaction JWS issued by Apple App Store. StoreKit 2 is the set of in-app purchase features that Apple provides for iOS and macOS apps; when a payment finishes, it issues a JWS, which is a signed string of the transaction information. Pass the value returned by StoreKit 2's jwsRepresentation as is, in its three parts: header, payload, and signature. For how the app client prepares it, see Prepare Apple receipt information.
  • accountUuid: Pass the same value you put in appAccountToken of the Apple purchase request. The result of the server comparing the two values is returned as hiveAxylAccountUuidCompare in the response.
  • price: If the amount differs, the request is rejected with PRICE_VERIFY_FAIL.
  • storeTransactionId: Apple transaction ID
  • providerId: GOOGLE
  • axylReceipt: The purchaseToken string issued by Google Play. A JSON string that contains purchase_data and signature is also accepted; in that case, put the original string returned by getOriginalJson() of the Google Play Billing Library in purchase_data as is. If you reserialize the value, signature verification fails. For how the app client prepares it, see Prepare Google receipt information.
  • productId: The purchase token contains no product information, so you must pass it. If omitted, the response is INVALID_REQUEST.
  • accountUuid: Pass the same value you put in ObfuscatedAccountId of the Google purchase request. The result of the server comparing the two values is returned as hiveAxylAccountUuidCompare in the response.
  • price: The request is not rejected even if the amount differs.
  • storeTransactionId: Google Play store transaction ID
  • providerId: STEAM
  • axylReceipt: The sealed receipt issued by the Hive Axyl server. Pass the AxylReceipt value that the app client received in the response when it started or restored a purchase as is, without modifying it. The server reseals the receipt with the saved order information and compares the two, so if the value has been forged or tampered with, the response is RECEIPT_VERIFY_FAIL. For how the app client prepares it, see Prepare Steam receipt information.
  • productId: Not used for comparison, because verification is based on the order information saved on the server.
  • accountUuid: The value you pass is saved in the payment history and serves as the basis for identifying which user made the payment. Steam has no payment-side account information to compare against, so hiveAxylAccountUuidCompare in the response is always 9.
  • price: The request is not rejected even if the amount differs.
  • orderId, storeTransactionId: The Steam order number, which consists of digits. If you send neither value, the server extracts the order number from axylReceipt, so you can omit them.
  • providerId: PG
  • axylReceipt: The sealed receipt issued by the Hive Axyl server. Pass the AxylReceipt value of the undelivered order that the app client received from Get completed payment information as is, without modifying it. The server reseals the receipt with the saved order information and compares the two, so if the value has been forged or tampered with, the response is RECEIPT_VERIFY_FAIL.
  • productId: Not used for comparison, because verification is based on the order information saved on the server.
  • accountUuid: The value you pass is saved in the payment history and serves as the basis for identifying which user made the payment. PG has no payment-side account information to compare against, so hiveAxylAccountUuidCompare in the response is always 9.
  • price: If the amount differs, the request is rejected with PRICE_VERIFY_FAIL.
  • orderId, storeTransactionId: The PG order number that starts with H. If you send neither value, the server extracts the order number from axylReceipt, so you can omit them.

Call example

curl -X POST 'https://commerce-api.hiveaxyl.com/payment/v1/purchase/verify' \
  -H 'Authorization: Bearer {access-token}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-App-Id: {app-id}' \
  -d '{
    "providerId": "APPLE",
    "requestType": 1,
    "axylReceipt": "{apple-transaction-jws}",
    "productId": "com.game.item.gold_100",
    "price": 1200,
    "currency": "KRW",
    "accountUuid": "123e4567-e89b-12d3-a456-426614174000",
    "storeTransactionId": "2000000123456789",
    "iapPayload": "iap_payload_data"
  }'
curl -X POST 'https://commerce-api.hiveaxyl.com/payment/v1/purchase/verify' \
  -H 'Authorization: Bearer {access-token}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-App-Id: {app-id}' \
  -d '{
    "providerId": "GOOGLE",
    "requestType": 1,
    "axylReceipt": "{google-purchase-token}",
    "productId": "com.game.item.gold_100",
    "price": 1200,
    "currency": "KRW",
    "accountUuid": "123e4567-e89b-12d3-a456-426614174000",
    "storeTransactionId": "GPA.3389-9543-8198-17604",
    "iapPayload": "iap_payload_data"
  }'
curl -X POST 'https://commerce-api.hiveaxyl.com/payment/v1/purchase/verify' \
  -H 'Authorization: Bearer {access-token}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-App-Id: {app-id}' \
  -d '{
    "providerId": "STEAM",
    "requestType": 1,
    "axylReceipt": "{steam-axyl-receipt}",
    "productId": "com.game.item.gold_100",
    "price": 1200,
    "currency": "KRW",
    "accountUuid": "123e4567-e89b-12d3-a456-426614174000",
    "storeTransactionId": "421799706624185538",
    "iapPayload": "iap_payload_data"
  }'
curl -X POST 'https://commerce-api.hiveaxyl.com/payment/v1/purchase/verify' \
  -H 'Authorization: Bearer {access-token}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-App-Id: {app-id}' \
  -d '{
    "providerId": "PG",
    "requestType": 1,
    "axylReceipt": "{pg-axyl-receipt}",
    "productId": "com.game.item.gold_100",
    "price": 1200,
    "currency": "KRW",
    "accountUuid": "123e4567-e89b-12d3-a456-426614174000",
    "storeTransactionId": "H517815844374710159",
    "iapPayload": "iap_payload_data"
  }'

Response

For the common data and meta, the error body, the product common error codes, and the receipt verification outcome.message values, see Payment responses and errors. This section describes the objects this API actually returns and the handling specific to this API.

Success response data object

Field Type Description
data.hiveAxylAccountUuidCompare integer Result of comparing accountUuid in the request with the purchase account identifier the market reported. 1 means a match, 2 a mismatch, and 9 that comparison is not possible. If 2 is returned, handle it according to your app's security policy; Hive Axyl does not automatically block the payment or product delivery. 9 is not a mismatch. Steam and PG always return 9.
data.hiveAxylCurrency string or null Verified payment currency. In the ISO 4217 three-letter format.
data.hiveAxylDuplicated boolean Whether the receipt verification is a duplicate. true means the receipt was already verified, so no new verification record was created and the existing result was returned as is.
data.hiveAxylGameServerPriceVerifyKey string or null App server payment amount verification key. When the payment was made with a custom amount, the verification key issued by the app server is returned as is.
data.hiveAxylPayload string or null The iapPayload value of the request, returned as is.
data.hiveAxylPrice number or null Verified payment amount. Based on the local currency, and includes decimals depending on the currency.
data.hiveAxylProductId string In-app product ID registered in the market.
data.hiveAxylProviderId string Market type. One of APPLE, GOOGLE, STEAM, and PG.
data.hiveAxylProviderTransactionId string Market-side transaction ID. For Apple it is the transactionId value, and for Google and Steam it is the orderId value.
data.hiveAxylPurchaseCancelState integer Payment cancellation status. 0 means normal and 1 means a canceled payment.
data.hiveAxylPurchaseTest string Whether it is a test payment. N means an actual payment and Y a test payment. It becomes Y for Apple when the environment of the verification result is Sandbox, for Google when the purchase type is a test purchase, and for Steam and PG according to the server's sandbox setting.
data.hiveAxylQuantity integer Purchase quantity.
data.hiveAxylReceipt string The axylReceipt sent in the request, returned by the server as is without modification.
data.hiveAxylReceiptVerifyResult object or null Original result object of the market receipt verification. Use it when the app server needs additional verification. All date fields in the Apple result are in Unix epoch milliseconds. Always null for Steam.
data.hiveAxylStoreTransactionId string or null Store transaction ID. For Apple it is the transactionId value, and for Google the orderId value. For Steam, a value different from hiveAxylProviderTransactionId is returned.
data.hiveAxylTransactionId string Hive Axyl payment transaction ID, in the format of a prefix and a number joined by an underscore. The app client uses it as axylTransactionId when it saves the product delivery result with ItemResultAsync, so return this value from the app server to the app client.

Response example

{
  "data": {
    "hiveAxylAccountUuidCompare": 1,
    "hiveAxylCurrency": "KRW",
    "hiveAxylDuplicated": false,
    "hiveAxylGameServerPriceVerifyKey": "verify-key-001",
    "hiveAxylPayload": "iap_payload_data",
    "hiveAxylPrice": 1200,
    "hiveAxylProductId": "com.game.item.gold_100",
    "hiveAxylProviderId": "APPLE",
    "hiveAxylProviderTransactionId": "2000000123456789",
    "hiveAxylPurchaseCancelState": 0,
    "hiveAxylPurchaseTest": "N",
    "hiveAxylQuantity": 1,
    "hiveAxylReceipt": "{apple-transaction-jws}",
    "hiveAxylReceiptVerifyResult": { ... },
    "hiveAxylStoreTransactionId": "2000000123456789",
    "hiveAxylTransactionId": "{axyl-transaction-id}"
  },
  "meta": null
}
{
  "data": {
    "hiveAxylAccountUuidCompare": 1,
    "hiveAxylCurrency": "KRW",
    "hiveAxylDuplicated": false,
    "hiveAxylGameServerPriceVerifyKey": "verify-key-001",
    "hiveAxylPayload": "iap_payload_data",
    "hiveAxylPrice": 1200,
    "hiveAxylProductId": "com.game.item.gold_100",
    "hiveAxylProviderId": "GOOGLE",
    "hiveAxylProviderTransactionId": "GPA.3389-9543-8198-17604",
    "hiveAxylPurchaseCancelState": 0,
    "hiveAxylPurchaseTest": "N",
    "hiveAxylQuantity": 1,
    "hiveAxylReceipt": "{google-purchase-token}",
    "hiveAxylReceiptVerifyResult": { ... },
    "hiveAxylStoreTransactionId": "GPA.3389-9543-8198-17604",
    "hiveAxylTransactionId": "{axyl-transaction-id}"
  },
  "meta": null
}
{
  "data": {
    "hiveAxylAccountUuidCompare": 9,
    "hiveAxylCurrency": "KRW",
    "hiveAxylDuplicated": false,
    "hiveAxylGameServerPriceVerifyKey": "verify-key-001",
    "hiveAxylPayload": "iap_payload_data",
    "hiveAxylPrice": 1200,
    "hiveAxylProductId": "com.game.item.gold_100",
    "hiveAxylProviderId": "STEAM",
    "hiveAxylProviderTransactionId": "2026010100001",
    "hiveAxylPurchaseCancelState": 0,
    "hiveAxylPurchaseTest": "N",
    "hiveAxylQuantity": 1,
    "hiveAxylReceipt": "{steam-axyl-receipt}",
    "hiveAxylReceiptVerifyResult": null,
    "hiveAxylStoreTransactionId": "421799706624185538",
    "hiveAxylTransactionId": "{axyl-transaction-id}"
  },
  "meta": null
}
{
  "data": {
    "hiveAxylAccountUuidCompare": 9,
    "hiveAxylCurrency": "KRW",
    "hiveAxylDuplicated": false,
    "hiveAxylGameServerPriceVerifyKey": "verify-key-001",
    "hiveAxylPayload": "iap_payload_data",
    "hiveAxylPrice": 1200,
    "hiveAxylProductId": "com.game.item.gold_100",
    "hiveAxylProviderId": "PG",
    "hiveAxylProviderTransactionId": "{pg-transaction-id}",
    "hiveAxylPurchaseCancelState": 0,
    "hiveAxylPurchaseTest": "N",
    "hiveAxylQuantity": 1,
    "hiveAxylReceipt": "{pg-axyl-receipt}",
    "hiveAxylReceiptVerifyResult": { ... },
    "hiveAxylStoreTransactionId": "H517815844374710159",
    "hiveAxylTransactionId": "{axyl-transaction-id}"
  },
  "meta": null
}
{
  "type": "/errors/payment/verify-error",
  "title": "Verify Error",
  "status": 400,
  "detail": "Failed to verify the receipt with the market.",
  "instance": "/payment/v1/purchase/verify",
  "code": "verify_error",
  "outcome": {
    "code": 400,
    "message": "INVALID_RECEIPT"
  }
}

Notes for each API

If hiveAxylDuplicated is true, the same receipt has already been verified. The values returned in this case are the result of the first verification, so check the delivery history before you decide whether to deliver, so that you do not deliver the same product twice.

If hiveAxylPurchaseCancelState is 1, the payment was canceled. In this case, do not deliver the product.

If hiveAxylPurchaseTest is Y, it is a test payment. Decide whether to deliver products for test payments in the production environment according to your app's operating policy.

For Steam, the payment is confirmed when you call this API, so do not call it repeatedly with the same receipt without need. If you did not receive a response because of a network error or a similar problem and cannot tell whether the request was processed, resend the same request and check whether hiveAxylDuplicated in the response is true to see whether it has already been processed. For Steam, hiveAxylReceiptVerifyResult is always null, so check what to deliver with the hiveAxylPrice, hiveAxylProductId, and hiveAxylQuantity values.

If there are multiple undelivered PG orders, call this API once for each order. You cannot verify multiple orders in one request.

Response status

Status Content type Meaning Response header Response body or handling
200 application/json Verification succeeded - data contains the verification result.
400 application/problem+json Request error or payment product error - -
500 application/problem+json Server error - -

Error codes by API

Code Condition How to handle
app_not_found The app information for X-App-Id cannot be found. Check the App ID again in Project Settings > App ID.

Verify subscription product receipts

Server API

POST /payment/v1/subscription/verify

Rechecks a subscription receipt with Apple App Store or Google Play to verify that the subscription is valid. The response also contains the subscription expiration time and the refund time, so use this result to decide whether to deliver or reclaim subscription benefits. Subscription payments are supported only for Apple App Store and Google Play.

Subscription receipt verification is also requested only through this API. When the app client saves the subscription purchase information with PurchaseSubscriptionAsync and then passes the receipt information to the app server, the app server calls this API. For the implementation procedure for each payment provider, see Verify Apple subscription product receipts and Verify Google Play subscription product receipts.

Before calling the API

  • Caller: app server
  • Base URL
    • Production: https://commerce-api.hiveaxyl.com
    • Sandbox: https://sandbox-commerce-api.hiveaxyl.com
  • Authentication: Authorization: Bearer {access-token}
Warning

Put the token for the app server that you received from Issue a token in the authentication header. Keep the access token and the Client Secret used for token issuance only on the app server, and do not include them in the app client.

Call parameters

Name Location Type Required Description
X-App-Id header string true The App ID registered in the Hive Console.
X-SDK-Version header string false Client SDK version information.
X-Platform header string false Platform information.
X-OS-Version header string false Operating system version information.
Accept-Language header string false Client language setting.
traceparent header string false W3C Trace Context header for distributed tracing.
User-Agent header string false User-Agent information of the client application.
body body SubscriptionPurchaseVerifyRequest true Subscription receipt verification request information.

Request body SubscriptionPurchaseVerifyRequest

Field Type Required Description
accountUuid string(uuid) true Value that links the logged-in user to this subscription record. Put the value the app client created in Generate an AccountUuid. Auto-renewal notifications contain no user information, so this value is also used as the key to find the user who receives the benefits on renewal. If you send a different value with each request, the previous payment record cannot be found on auto-renewal or purchase restoration, and iapPayload cannot be restored.
appVersion string false App version.
axylReceipt string true Subscription purchase receipt. The value to put differs by market, so see Request values by market.
country string true Country code. Uses the ISO 3166-1 two-letter format.
currency string false Currency. Uses the ISO 4217 three-letter format.
iapPayload string false Payload defined by the app. The value you send is saved as is and returned as hiveAxylPayload in the response.
language string true Language code. Uses the ISO 639-1 two-letter format.
projectInfo object false Additional information for each app.
providerId string true Market type. Subscriptions support only APPLE and GOOGLE.
requestType integer true Request type. 1 is a new purchase and 2 is purchase restoration; only these two values are allowed.
serverId string false Server ID registered in App Info > App Server of the Hive Console. For details, see App server.
storeTransactionId string false Store transaction ID. How it is used differs by market, so see Request values by market.

Request values by market

The following fields take different values, or are processed differently by the server, depending on the market.

  • providerId: APPLE
  • axylReceipt: The original StoreKit 2 transaction JWS issued by Apple App Store. Pass the string, which consists of three parts (header, payload, and signature), as is.
  • accountUuid: Pass the same value you put in appAccountToken of the Apple purchase request. The result of the server comparing the two values is returned as hiveAxylAccountUuidCompare in the response.
  • storeTransactionId: If you pass the transaction JWS, the lookup key originalTransactionId is inside the receipt, so you can omit it. Even if you send a value with it, the value inside the receipt takes precedence.
  • providerId: GOOGLE
  • axylReceipt: The purchaseToken string issued by Google Play
  • accountUuid: Pass the same value you put in ObfuscatedAccountId of the Google purchase request. The result of the server comparing the two values is returned as hiveAxylAccountUuidCompare in the response.
  • storeTransactionId: You do not need to pass it. The server creates the lookup key from the market reverification result and does not use this value even if you pass it.

Call example

curl -X POST 'https://commerce-api.hiveaxyl.com/payment/v1/subscription/verify' \
  -H 'Authorization: Bearer {access-token}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-App-Id: {app-id}' \
  -d '{
    "providerId": "APPLE",
    "axylReceipt": "{apple-transaction-jws}",
    "country": "KR",
    "language": "ko",
    "currency": "KRW",
    "accountUuid": "123e4567-e89b-12d3-a456-426614174000",
    "requestType": 1,
    "serverId": "server01",
    "iapPayload": "iap_payload_data"
  }'
curl -X POST 'https://commerce-api.hiveaxyl.com/payment/v1/subscription/verify' \
  -H 'Authorization: Bearer {access-token}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-App-Id: {app-id}' \
  -d '{
    "providerId": "GOOGLE",
    "axylReceipt": "{google-purchase-token}",
    "country": "KR",
    "language": "ko",
    "currency": "KRW",
    "accountUuid": "123e4567-e89b-12d3-a456-426614174000",
    "requestType": 1,
    "serverId": "server01",
    "iapPayload": "iap_payload_data"
  }'

Response

For the common data and meta, the error body, the product common error codes, and the receipt verification outcome.message values, see Payment responses and errors. This section describes the objects this API actually returns and the handling specific to this API.

Success response data object

Field Type Description
data.hiveAxylAccountUuidCompare integer Result of comparing accountUuid in the request with the account identifier in the market verification result. 1 means a match, 2 a mismatch, and 9 that comparison is not possible. If 2 is returned, handle it according to your app's security policy; Hive Axyl does not automatically block the payment or benefit delivery. 9 is not a mismatch.
data.hiveAxylAutoRenewProductId string or null Product ID to be renewed in the next cycle. If it differs from hiveAxylProductId, the product changes in the next cycle; if it is the same, the subscription renews as is. If auto-renewal is off, it is null. For Apple, it is the renewalInfo.autoRenewProductId value; for Google, the current product ID is returned if no product replacement is scheduled.
data.hiveAxylCurrency string or null Currency code. It is the value the server received from the market, so it can differ from the request value; if the currency cannot be obtained from the market, it is null.
data.hiveAxylDuplicated boolean true if the receipt has already been verified. Even when it is true, the verification itself succeeded; only the duplicate save is skipped.
data.hiveAxylExpiresDate integer or null Subscription expiration time. In Unix epoch milliseconds; null if the market does not provide the value.
data.hiveAxylOriginalStoreTransactionId string or null Transaction ID of the first payment. Every cycle of this subscription has the same value, so look at it together with hiveAxylStoreTransactionId to tell whether it is a renewal or a new subscription. For Apple, it is originalTransactionId; for Google, it is the order ID of the first payment.
data.hiveAxylPayload string or null The iapPayload value of the request, returned as is.
data.hiveAxylPrice number or null Verified payment amount. It is the value the server received from the market: for Apple, it is the unit price set in App Store Connect, and for Google, it is the total amount including tax, so the values from the two markets have different meanings. null if the amount cannot be obtained from the market.
data.hiveAxylProductId string Verified subscription product ID. It is based on the market verification result, so it can differ from the request value.
data.hiveAxylQuantity integer Purchase quantity. Subscriptions cannot be sold in bundled quantities, so it is 1.
data.hiveAxylReceiptVerifyResult object Original market verification result. It is the entire value that the server received from the market and normalized; use it when the app server needs to make additional decisions.
data.hiveAxylRefundDate integer or null Refund time. In Unix epoch milliseconds; null if not refunded. For Google, the market does not provide the refund time, so it is always null.
data.hiveAxylStoreTransactionId string Market transaction ID. For Apple, it is the originalTransactionId value, and for Google, the orderId value; use it to identify and reconcile subscriptions.
data.hiveAxylTransactionId string(uuid) Transaction ID of the verification record. If hiveAxylDuplicated is true, the value issued at the first verification is returned as is.

Response example

{
  "data": {
    "hiveAxylAccountUuidCompare": 1,
    "hiveAxylAutoRenewProductId": "com.test.sub.monthly",
    "hiveAxylCurrency": "KRW",
    "hiveAxylDuplicated": false,
    "hiveAxylExpiresDate": 1785376709000,
    "hiveAxylOriginalStoreTransactionId": "2000000000000001",
    "hiveAxylPayload": "iap_payload_data",
    "hiveAxylPrice": 1200,
    "hiveAxylProductId": "com.test.sub.monthly",
    "hiveAxylQuantity": 1,
    "hiveAxylReceiptVerifyResult": { ... },
    "hiveAxylRefundDate": null,
    "hiveAxylStoreTransactionId": "2000000000000001",
    "hiveAxylTransactionId": "019fc59f-8340-7656-b91e-3a47d465e594"
  },
  "meta": null
}
{
  "data": {
    "hiveAxylAccountUuidCompare": 1,
    "hiveAxylAutoRenewProductId": "com.test.sub.monthly",
    "hiveAxylCurrency": "KRW",
    "hiveAxylDuplicated": false,
    "hiveAxylExpiresDate": 1785376709000,
    "hiveAxylOriginalStoreTransactionId": "GPA.3301-9758-9251-77321",
    "hiveAxylPayload": "iap_payload_data",
    "hiveAxylPrice": 1200,
    "hiveAxylProductId": "com.test.sub.monthly",
    "hiveAxylQuantity": 1,
    "hiveAxylReceiptVerifyResult": { ... },
    "hiveAxylRefundDate": null,
    "hiveAxylStoreTransactionId": "GPA.3389-9543-8198-17604",
    "hiveAxylTransactionId": "019fc59f-8340-7656-b91e-3a47d465e594"
  },
  "meta": null
}

Notes for each API

If hiveAxylRefundDate has a value, the subscription was refunded. In this case, reclaim the subscription benefits. For Google subscriptions, hiveAxylRefundDate is always null, so do not use this value to determine whether a refund occurred. If you need the original information that the market provided, check hiveAxylReceiptVerifyResult.

hiveAxylExpiresDate is the time the subscription expires. After this time passes, do not maintain the subscription benefits.

If hiveAxylDuplicated is true, the receipt has already been verified. The verification itself succeeded, so do not treat it as an error; check the delivery history so that you do not deliver the same subscription benefits again.

Response status

Status Content type Meaning Response header Response body or handling
200 application/json Verification succeeded - data contains the verified subscription information.
400 application/problem+json Request error or payment product error - -
500 application/problem+json Server error - -

Get purchase history

Server API

POST /payment/v1/transactions

Retrieves the purchase history from Google Play, Apple App Store, Steam, and PG. Check each user's purchase history and use it to handle payment inquiries and for operational checks. You can specify only one payment provider per request, so if you need the purchase history of multiple payment providers, retrieve it for each provider.

Items are returned starting from the newest, based on the verification processing time; if there are many results, use the cursor to continue retrieving the next page.

Before calling the API

  • Caller: app server
  • Base URL
    • Production: https://commerce-api.hiveaxyl.com
    • Sandbox: https://sandbox-commerce-api.hiveaxyl.com
  • Authentication: Authorization: Bearer {access-token}
Warning

Put the token for the app server that you received from Issue a token in the authentication header. Keep the access token and the Client Secret used for token issuance only on the app server, and do not include them in the app client.

Call parameters

Name Location Type Required Description
X-App-Id header string true The App ID registered in the Hive Console.
X-SDK-Version header string false Client SDK version information.
X-Platform header string false Platform information.
X-OS-Version header string false Operating system version information.
Accept-Language header string false Client language setting.
traceparent header string false W3C Trace Context header for distributed tracing.
User-Agent header string false User-Agent information of the client application.
body body TransactionRequest true Purchase history retrieval conditions.

Request body TransactionRequest

Field Type Required Description
cursor string false When you retrieve the next page, pass the meta.page.nextCursor value from the previous response as is, without modifying it. Omit it for the first page.
endDate string(date-time) false Retrieval end time. In UTC; if omitted, the current time is used. It must be later than startDate.
providerId string true Payment provider to retrieve. Specify one of APPLE, GOOGLE, PG, and STEAM.
size integer false Number of items per page. Specify 1 to 100; the default value is 20.
startDate string(date-time) true Retrieval start time. In UTC.
targetPlayerId integer(int64) false Filters the results by the Player ID of a specific user. Available only when you call with the token for the app server; if omitted, the Player ID of the authentication token is used.
transactionId string false Retrieves a single item by store purchase number. Returns the transaction that exactly matches storeTransactionId in the response.

Call example

curl -X POST 'https://commerce-api.hiveaxyl.com/payment/v1/transactions' \
  -H 'Authorization: Bearer {access-token}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-App-Id: {app-id}' \
  -d '{
    "providerId": "GOOGLE",
    "startDate": "2026-04-16T00:00:00",
    "endDate": "2026-05-16T23:59:59",
    "size": 20,
    "targetPlayerId": 12345
  }'

Response

For the common data and meta, the error body, and the product common error codes, see Payment responses and errors. This section describes the objects this API actually returns and the handling specific to this API.

Success response data object

Field Type Description
data array List of purchase history items. The items are ordered from the newest, based on verifiedDate.

Nested success response object data[]

Field Type Description
providerId string Payment provider. One of APPLE, GOOGLE, PG, and STEAM.
purchaseAmount string Purchase amount.
purchaseCurrency string Purchase currency.
purchaseDate string(date-time) Time related to the purchase. In UTC; which event's time it is differs by payment provider. For Apple and Google, it is the store payment time; for PG, the payment confirmation time; and for Steam, the order creation time. The Steam value is earlier than the actual payment time, so do not use it as is for settlement reconciliation. If the value cannot be determined, it contains the same value as verifiedDate; check which event it is with purchaseDateSource.
purchaseDateSource string Indicates which event's time purchaseDate is. STORE_PAYMENT is the store payment time, PAYMENT_CONFIRMED the payment confirmation time, and ORDER_CREATED the order creation time; VERIFIED means that the actual purchase time is unknown, so verifiedDate was used as is.
storeTransactionId string Purchase number for each store. For Apple, it is the transactionId value; for Google, PG, and Steam, it is the orderId value.
transactionId string(uuid) Hive Axyl transaction ID.
verifiedDate string(date-time) Verification processing time. In UTC; it is the basis for list sorting and for the cursor.

Success response meta object

Field Type Description
meta.page.hasNext boolean true if there is a next page.
meta.page.nextCursor string or null Cursor used to retrieve the next page.
meta.page.hasPrevious null This API does not support retrieving the previous page, so it is always null.
meta.page.previousCursor null This API does not support retrieving the previous page, so it is always null.

API-specific additional error object

In a 400 error response, the cause of the failure is identified by the following outcome.message values.

  • UNAUTHORIZED_REQUEST: Authentication failed
  • FORBIDDEN_REQUEST: A request that specified targetPlayerId while calling with a user login token
  • INVALID_CURSOR: Invalid cursor format
  • CURSOR_CONTEXT_MISMATCH: Retrieval conditions changed while paging

Response example

{
  "data": [
    {
      "providerId": "GOOGLE",
      "purchaseAmount": "1200",
      "purchaseCurrency": "KRW",
      "purchaseDate": "2026-05-16T12:34:56",
      "purchaseDateSource": "STORE_PAYMENT",
      "storeTransactionId": "GPA.3312-1234-5678-90123",
      "transactionId": "019fc59f-8340-7656-b91e-3a47d465e594",
      "verifiedDate": "2026-05-16T12:35:10"
    }
  ],
  "meta": {
    "page": {
      "hasNext": true,
      "nextCursor": "{next-cursor}",
      "hasPrevious": null,
      "previousCursor": null
    }
  }
}

Notes for each API

The retrieval period is up to 30 days. This limit applies even if you omit endDate. However, when you retrieve a single item by transactionId, there is no period limit, so you can also find old orders.

Omit cursor in the first request. If meta.page.hasNext in the response is true, put the meta.page.nextCursor value as is in cursor of the next request and call again. The cursor also contains the retrieval conditions of the first request, so if you change providerId, the retrieval period, transactionId, or targetPlayerId in the next request, a CURSOR_CONTEXT_MISMATCH error is returned. To change the conditions, retrieve again from the first page.

This API retrieves in only one direction, starting from the newest items. It does not provide a cursor that goes back to the previous page, so to check earlier pages again, retrieve from the first page.

Caution

Purchase history items tell you the payment amount, the time, and the transaction number. Do not use this response to determine refunds and cancellations.

Response status

Status Content type Meaning Response header Response body or handling
200 application/json Retrieval succeeded - data contains the purchase history list, and meta.page contains the cursor information.
400 application/problem+json Request error or payment product error - -
500 application/problem+json Server error - -

Error codes by API

Code Condition How to handle
payment_forbidden The request is not allowed. Check the cause with outcome.message in the response.