Skip to content

Step 5. Deliver products

When receipt verification is complete, the app server delivers the product to the user, and the app client finalizes the purchase for the PG payment and then records the delivery result in the Hive Axyl server. The hiveAxylTransactionId that the app client uses in this step is the value that the app server received in the receipt verification response and passed on.

1. Deliver products

After checking the receipt verification result, the app server delivers the product to the user who paid. Your app implements product delivery, and the delivery method can differ from app to app.

Finalize the purchase only after the app server finishes delivering the product. Retrieving undelivered orders finds only orders that are not closed, so if you close an order by finalizing the purchase before delivery, you cannot find that order again when the app stops during delivery.

2. Finalize the purchase

Perform the final purchase finalization for the PG payment. This changes the payment status to completed and updates the related data.

Purchase finalization puts the order in the consumed state. If you skip this step, the paid order remains in the unconsumed state and keeps appearing in the undelivered order results of Restore purchases.

Method

FinalizePurchaseAsync

To implement purchase finalization, call FinalizePurchaseAsync() provided by the Hive Axyl SDK. It performs the final purchase finalization of the PG payment, changes the payment status to completed, and updates the related data.

Call parameters

Field name Type Required Description
request PurchaseFinalizeRequest Required The request data for purchase finalization.
context ApiCallContext Optional Per-call settings object that specifies the idempotency key, cancellation token, and request policy. If omitted, the default values are used.

PurchaseFinalizeRequest

Field name Type Required Description
AxylReceipt string Required Pass the AxylReceipt of the undelivered order returned by Get completed payment information exactly as is. It is the same value as the sealed receipt that you passed when you requested receipt verification from the app server. The server decrypts this value to find the order to finalize, so if you modify the value, the request is rejected.
ProviderId PurchaseFinalizeRequestProviderId Required The market identifier. Because this request is for PG purchase finalization only, specify only Pg.

Call example

Check the success result of PaymentsFinalizePurchaseResult and the domain-specific results (Outcome) defined by this method in the example below and in the response status. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.

using Hive.Axyl.Payments;
using Hive.Axyl.Core;

// payments: IPaymentsService registered during initialization (see the Install the module, initialize, and log in guide)
IPaymentsService payments = HiveCore.Resolve<IPaymentsService>();

var request = new PurchaseFinalizeRequest
{
    AxylReceipt = axylReceipt, // AxylReceipt returned by the undelivered order query. The same value that was passed when requesting verification from the app server
    ProviderId = PurchaseFinalizeRequestProviderId.Pg
};

PaymentsFinalizePurchaseResult result = await payments.FinalizePurchaseAsync(request);

switch (result)
{
    case PaymentsFinalizePurchaseResult.Success success:
        // Purchase finalized. Check the PG order number and the Axyl transaction number
        Debug.Log($"orderId: {success.Data.OrderId}, storeTransactionId: {success.Data.StoreTransactionId}");
        break;

    case PaymentsFinalizePurchaseResult.PaymentBadRequest:
        // The request cannot be processed. Check the request values and call conditions
        break;

    case PaymentsFinalizePurchaseResult.PaymentInvalidParameter:
        // Invalid parameter. Check the request values
        break;

    // Handle common Failure
    case PaymentsFinalizePurchaseResult.Failure failure:
        HiveError err = failure.Problem;
        Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
        break;

    // Safety net: unhandled results and unknown new results (UnknownOutcome)
    default:
        Debug.LogWarning($"Unhandled result: {result.GetType().Name}");
        break;
}

Response data

On success, the result is contained in Data (PurchaseFinalizeResponseData) of PaymentsFinalizePurchaseResult.Success.

Field name Type Required Description
Data.OrderId string Optional The PG order number. It is a string that starts with H.
Data.StoreTransactionId string Optional The Hive Axyl transaction number.
Data.Meta string? Optional Response meta information.

Response example

// Example of success.Data in the Success branch
// success.Data.OrderId = "H517815844374710159"
// success.Data.StoreTransactionId = "3390549843"

Response status

The following table summarizes the success result of PaymentsFinalizePurchaseResult and the domain-specific results (Outcome) defined by this method. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.

Response case Description App client handling
Success The payment status was changed to completed. Check the order number and transaction ID, and then proceed to the next step
PaymentBadRequest The request cannot be processed. Check the request values and call conditions
PaymentInvalidParameter Invalid parameter (for example, a required value is missing). Check and fix the required field values
PaymentResourceNotFound The payment information cannot be found. Check the receipt, order number, and payment status
UnknownOutcome A domain-specific result that the SDK does not recognize. Treat it as a failure and log the result code
Failure Common Failure. See Common error handling. Handle it according to the common error handling guidelines

3. Save product delivery results

After the app server completes product delivery, record the delivery result, such as success or cancellation, in the Hive Axyl server.

Method

ItemResultAsync

To implement saving delivery results for consumable products, call ItemResultAsync() provided by the Hive Axyl SDK. It records the result in the Hive Axyl server after product delivery is complete. This method does not confirm the payment or decide whether to deliver the product.

  • When to call: After the app server completes product delivery
  • AxylTransactionId value: The hiveAxylTransactionId that the app server received in the receipt verification response and passed on
  • Cancellation handling: If delivery fails, set a cancellation status value in Status

Call parameters

Field name Type Required Description
request ItemResultBody Required The request data object for saving consumable product delivery results.
context ApiCallContext Optional Per-call settings object that specifies the idempotency key, cancellation token, and request policy. If omitted, the default values are used.

ItemResultBody

Field name Type Required Description
AxylTransactionId string Required The Hive Axyl payment transaction ID (the prefix identifies the market). Use the hiveAxylTransactionId value that the app server received in the receipt verification response and passed on.
Status int Required The delivery result status. 1: delivery succeeded, 2: canceled without reclaiming the product, 3: canceled and the product reclaimed. Any other value is invalid.
Assets IReadOnlyList<ItemResultAsset> Optional The list of products actually delivered. If there are no items to record, omit this field.
ProjectPayloadInfo string Optional App-specific free-form JSON data (JSON string)

ItemResultAsset

Field name Type Required Description
AssetId string Optional Unique ID of the product in the app
AssetName string Optional Name of the product in the app
Quantity int Optional The delivered quantity. If specified, it must be 1 or more.

Call example

Check the success result of PaymentsItemResultResult and the domain-specific results (Outcome) defined by this method in the example below and in the response status. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.

using Hive.Axyl.Payments;
using Hive.Axyl.Core;

// payments: IPaymentsService registered during initialization (for how to retrieve it, see [Install and initialize the module](../init.md))
IPaymentsService payments = HiveCore.Resolve<IPaymentsService>();

// After product delivery is complete, create the request object with the delivery result
var request = new ItemResultBody
{
    AxylTransactionId = axylTransactionId, // hiveAxylTransactionId from the receipt verification response passed by the app server
    Status = 1, // 1: Delivery succeeded
    Assets = new[]
    {
        new ItemResultAsset { AssetId = "item_gold_100", AssetName = "골드 100개", Quantity = 1 }
    },
    ProjectPayloadInfo = "{\"serverId\":\"server01\"}" // (Optional) App-specific free-form JSON data
};

PaymentsItemResultResult result = await payments.ItemResultAsync(request);

switch (result)
{
    case PaymentsItemResultResult.Success success:
        // Delivery result recorded. You can check success.Data.Meta.
        break;

    // Request value problem — check the required values, quantity, and status value
    case PaymentsItemResultResult.PaymentInvalidParameter:
    case PaymentsItemResultResult.PaymentBadRequest:
        Debug.LogError("Check the request parameters.");
        break;

    // Handle common Failure
    case PaymentsItemResultResult.Failure failure:
        HiveError err = failure.Problem;
        Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
        break;

    // Safety net: unhandled results and unknown new results (UnknownOutcome)
    default:
        Debug.LogWarning($"Unhandled result: {result.GetType().Name}");
        break;
}

Response data

On success, the response meta information is contained in Data (SuccessResponseData) of PaymentsItemResultResult.Success.

Field name Type Required Description
Data.Meta string? Optional Response meta information.

Response example

// You can check success.Data.Meta in the Success branch.

Response status

The following table summarizes the success result of PaymentsItemResultResult and the domain-specific results (Outcome) defined by this method. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.

Response case Description App client handling
Success Delivery result recorded Proceed with the next payment processing
InvalidQuantity The delivered quantity is invalid. Check the delivered quantity
InvalidStatus The delivery result status value is invalid. Check the Status value
PaymentBadRequest The request cannot be processed. Check the request values and call conditions
PaymentInvalidParameter When a parameter is invalid (for example, AxylTransactionId is missing) Check the required parameter settings
PaymentResourceNotFound The payment information cannot be found. Check the receipt, order number, and payment status
UnknownOutcome A domain-specific result that the SDK does not recognize. Treat it as a failure and log the result code
Failure Common Failure. See Common error handling. Handle it according to the common error handling guidelines

Learn more

If a product could not be delivered during the payment process because of a network error or a similar problem, implement Restore purchases.