Skip to main content

TapPayments Global Payment System

TapPayments-Global is a service that allows you to sell virtual goods in your game.

You can sell the following types of goods in TapPayments-Global:

  • Consumable goods
  • Non-consumable goods

Below are their differences:

TypeDescription
Consumable goodsConsumable goods are goods that can be purchased repeatedly by the user and which, when consumed, provide the player with certain in-game content. Examples are currency and props.
Non-consumable goodsNon-consumable goods are those that can be used permanently once purchased, such as level-ups and DLC.

With the TapTap Developer Center, you can easily create in-game goods and seamlessly access TapPayments-Global's services in your game to sell goods.

Integrating the SDK

Environment Requirements

  • Supports Unity 2019.4 or higher.

Getting Ready

  1. Refer to Before You Start to create an app, enable app configuration, and bind API domains;
  2. Refer to TapSDK Quickstart to configure package name and signature certificate;

To use TapPayments-Global, you must depend on the following libraries:

  • TapTap.Login
  • TapTap.Common
  • TapTap.Bootstrap

Getting the SDK

The SDK can be imported through the Unity Package Manager or manually imported, either of which can be selected as needed for the project.

Method 1: Use the Unity Package Manager

"dependencies":{
"com.taptap.tds.login":"https://github.com/TapTap/TapLogin-Unity.git#3.26.0",
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.26.0",
"com.taptap.tds.bootstrap":"https://github.com/TapTap/TapBootstrap-Unity.git#3.26.0",
"com.taptap.tds.payments.global":"https://github.com/taptap/TapPayments-Global-Unity.git#3.26.0",
"com.leancloud.realtime": "https://github.com/leancloud/csharp-sdk-upm.git#realtime-2.3.0",
"com.leancloud.storage": "https://github.com/leancloud/csharp-sdk-upm.git#storage-2.3.0",
"com.taptap.tds.androiddependencyresolver": "https://github.com/TapTap/Android_Dependency_Resolver#1.1.5"
}

Method 2: Manual Import

  1. On the Downloads page, find the TapSDK Unity and LeanCloud C# SDK download links and download TapSDK-UnityPackage.zip and LeanCloud-SDK-Realtime-Unity.zip respectively.

  2. In the Unity project, go to Assets > Import Packages > Custom Packages and select the TapSDK packages you want to use in your game from the unzipped TapSDK-UnityPackage.zip, where:

    • TapTap_Bootstrap.unitypackage is the TapSDK starter (required).
    • TapTap_Common.unitypackage is the TapSDK basic library (required).
    • TapTap_Login.unitypackage is TapTap login (required).
    • TapTap_PaymentsGlobal.unitypackage is the TapTap payment module (required).
    • TapTap_Android_Dependency_Resolver.unitypackage TapTap Android Dependency Resolver (required for Android).
  3. The unzipped LeanCloud-SDK-Realtime-Unity.zip is the Plugins folder. Drag and drop it into Unity.

tip

There are no version requirements for kotlin-stdlib and okhttp.

TapSDK Initialization

If you have completed the initialization by following the Quickstart, you only need to import the payment module here.

var config = new TapConfig.Builder()  
.ClientID(clientId) // Required, corresponds to Client ID in Developer Center
.ClientToken(clientToken) // Required, corresponds to Client Token in Developer Center
.ServerURL(serverUrl) // Required, Developer Center > Your Game > Game Services > Configuration > Domain > API
.RegionType(RegionType.IO) // Required, CN indicates Mainland China, IO indicates other countries or regions
.ConfigBuilder();

TapBootstrap.Init(config);

Payment Module Initialization

After integrating the TapTap SDK with Unity, you can initialize the payment module through the following method:

Set android:name to com.taptap.payment.api.UnityApplication under Application tag in Unity's LauncherManifest.xml for initialization.

<application
android:name="com.taptap.payment.api.UnityApplication">
...
</application>

If you need to customize the Android Application class, please refer to the Android example.

SDK Guide

Query Items

string language = "en_US";  

string[] itemIds = new [] { "product01", "product02", "product03" };

TapPayment.QueryItems (language, itemIds, new TapPayment.Callback < Item [] > ()
{
OnFinish = items =>
{
if ( items == null || items.Length == 0 )
{
Console.WriteLine ( "No items found" );
}
else
{
foreach ( var item in items )
{
Console.WriteLine ( item );
}
}
},

OnError = error =>
{
Console.WriteLine ( error );
}
} );

// Or use the language-free version of the function, and the SDK will automatically select the appropriate language based on the user's country or region
TapPayment.QueryItems (itemIds, new TapPayment.Callback < Item [] > ()
{
...
} );

Parameter description:

  • String language: The needed internationalization language code, such as: zh_CN, en_US, ja_JP, etc. If you do not need to customize the language/country or want to use the TapSDK for unified settings, you can use the language-free version of the function, and the SDK will automatically select the corresponding language based on the user's country or region.
  • String[] itemIds: The array of item IDs to be queried. The item ID is the ID of the item defined by the game in Developer Center > Your Game > Game Services > TapTap Payments > Items and Orders. Item is the callback result for the items found.
  • Callback<Item[]> callback: Callback Object
    • Successful callback type: array of Item information: (Array<Item> items)
    • Failure callback type: Error: (Error error)

Launch in-app purchase

string language = "en_US";

string itemId = "product01";

int quantity = 1;

string extra = "Custom extension information";

TapPayment.RequestPayFlow (language, itemId, quantity, extra, new TapPayment.PayCallback ()
{
OnCancel = ( extra ) =>
{
Console.WriteLine ( $"Payment canceled\n{extra}" );
},

OnError = ( error, extra ) =>
{
Console.WriteLine ( $"Error code:{error.code}\nError message:{error.Message}\n{extra}");
},


OnFinish = ( order, extra ) =>
{
Console.WriteLine ( $"Order information:{order}\n{extra}" );
}
} );

// Or use the language-free version of the function, and the SDK will automatically select the appropriate language based on the user's country or region
TapPayment.RequestPayFlow (itemId, quantity, extra, new TapPayment.PayCallback ()
{
...
} );

Parameter description:

  • String language: The needed internationalization language code, such as: zh_CN, en_US, ja_JP, etc. If you do not need to customize the language/country or want to use the TapSDK for unified settings, you can use the language-free version of the function, and the SDK will automatically select the corresponding language based on the user's country or region.
  • String itemId: The ID of the item to be purchased. The item ID is the ID of the item defined by the game in Developer Center > Your Game > Game Services > TapTap Payments > Items and Orders.
  • Int quantity: The quantity of items to be purchased.
  • String extra: Additional extension information, which will be returned in the payment process callback. Even if the order fails to be paid, it will be bound to the order.
  • PayCallback: Callback Object.
    • When the payment process is completed, the callback type is the order information Order and custom extension information: (Order, String extra)
    • When the payment process fails, the callback type is the exception Error and custom extension information: (Error, String extra)
    • When the user cancels the payment process, the callback type is the custom extension information: (String extra)

Query order

String orderId = "Order ID";

TapPayment.QueryOrder ( orderId, new TapPayment.Callback < Order > ()
{
OnFinish = ( order ) =>
{
Console.WriteLine ( $"Order information: {order}" );
},

OnError = ( error ) =>
{
Console.WriteLine ( $"Error code: {error.code}\nError message: {error.Message}" );
}
} );

// Or pass in an existing order object directly
Order order = new Order();
order.id = "Order ID";
TapPayment.QueryOrder ( orderId, new TapPayment.Callback < Order > ()
{
...
} );

Parameter description:

  • String orderId: The order ID to be queried.
  • Callback<Order> callback: Callback Object
    • Successful callback type is order information Order: (Order order)
    • Failure callback type is exception Error: (Error error)

Parameter description:

  • Order order: Existing order object.
  • Callback<Order> callback: Callback Object.
    • Successful callback type is order information Order: (Order order)
    • Failure callback type is exception Error: (Error error)
Arguments

The order information contains the order ID. You can pass it in directly, or you can only pass in the order ID. When the query is successful, the status field [State state] of the order information (Order order) may be updated.

Verify order

String orderId = "Order ID";  
String orderToken = "Order Token";

TapPayment.ConsumeOrder ( orderId, orderToken, new TapPayment.Callback < Order > ()
{
OnFinish = ( order ) =>
{
Console.WriteLine ( $"Order information: {order}" );
},

OnError = ( error ) =>
{
Console.WriteLine ( $"Error code: {error.code}\nError message: {error.Message}" );
}
} );

// Or pass in an existing order object directly
Order order = Existing order object
TapPayment.ConsumeOrder ( order, new TapPayment.Callback < Order > ()
{
...
} );

Parameter description:

  • String orderId: The order ID to be verified.
  • String orderToken: The order token to be verified.
  • Callback<Order> callback: Callback Object
    • Successful callback type is order information Order: (Order order)
    • Failure callback type is exception Error: (Error error)

Parameter description:

  • Order order: Existing order object.
  • Callback<Order> callback: Callback Object
    • Successful callback type is order information Order: (Order order)
    • Failure callback type is exception Error: (Error error)
Arguments

The order information contains the order ID and the order token. You can pass it in directly, or you can only pass in the order ID and order token. When the order is verified successfully, the state field [State state] of the order information (Order order) returned in the callback will be updated to COMPLETED.

Item information Item

FieldTypeDescription
typeintItem type
idstringItem ID
namestringItem name
descriptionstringItem description
pricedecimalItem price
currencystringCurrency unit
regionIdstringItem region
languageIdstringItem language

Order Order

FieldTypeDescription
itemIdstringItem ID
pricedecimalItem price
taxdecimalTax
currencyStringCurrency unit
quantityintThe quantity of items purchased
extraStringCustom information defined by the developer
idStringOrder ID
tokenStringOrder token
stateStateOrder status
channelStringPayment channel
feedecimalChannel fee rate
clientIdStringClient ID
userIdStringUser OpenID
regionIdStringUser region ID
Order State Order.State
EnumerationValueDescription
UNKNOWN0Unknown status.
PAYMENT_PENDING2Payment pending.
PAID3Paid.
COMPLETED4The order has been paid and the props have been issued.
PAYMENT_TIMEOUT5Payment timed out.
REFUNDING20Refunding.
REFUNDED21Refund successful.
REFUND_FAILED22Refund failed.
REFUND_REJECTED23Refund rejected.

Exception Error

/// <summary> 
/// Payment Exception class.
/// </summary>
public class Error : Exception
{
/// <summary>
/// Error code
/// </summary>
public Code code;
/// <summary>
/// The constructor of Error
/// Create a payment error object containing the payment error code and information.
/// </summary>
/// <param name="code">Error code</param>
/// <param name="message">Error message</param>
public Error ( Code code, string message ) : base ( message )
{
this.code = code;
}
public override string ToString ()
{
return "Error(" + "code=" + code + ", message=" + this.Message + ')';
}
}
EnumerationValueDescription
UNKNOWN-1Unknown error
OK0Normal
ILLEGAL_ARGUMENT1Illegal argument
NETWORK_ERROR2Network error
INTERNAL_SERVER_ERROR3Internal server error
NOT_LOGIN401User not logged in
TOO_MANY_REQUEST1003Too many requests
ITEM_NOT_FOUND1001Item does not exist
ITEM_INFO_CHANGE1017Item information has changed
REPEAT_PURCHASE_NON_CONSUMABLE_GOODS1002Repeat purchase of non-consumable goods
ORDER_NOT_FOUND1004Order does not exist
ORDER_CREATE_FAILED1005Failed to create order
ORDER_PAID1006Order paid
ORDER_TIMEOUT1008Order timeout
ORDER_VERIFY_ERROR1018Order verification error
REGION_NOT_EDITABLE1007Region not editable

Payment Callback PayCallback

/// <summary>  
/// PayCallback is used as an asynchronous callback notification for payment request functions. Related functions are:
/// <ul>
/// <li><see cref="RequestPayFlow(string,int,string,TapTap.TapPay.TapPayment.PayCallback)"/></li>
/// <li><see cref="RequestPayFlow(string,string,int,string,TapTap.TapPay.TapPayment.PayCallback)"/></li>
/// </ul>
/// </summary>
public class PayCallback
{
/// <summary>
/// Cancel payment
/// Asynchronous callback when the user cancels the payment operation.
/// </summary>
/// <param name="extra"> Custom information defined by the developer
/// </param>
public delegate void CancelType ( string extra );

/// <summary>
/// Payment error
/// Asynchronous callback when an error occurs during payment.
/// </summary>
/// <param name="error"> Error information
/// Error information callback when an error occurs during payment. For details, see <see cref="Error"/>.
/// </param>
/// <param name="extra"> Custom information defined by the developer
///</param>
public delegate void ErrorType ( Error error, string extra );


/// <summary>
/// End of payment flow
/// Asynchronous callback when the payment flow is completed.
/// Note: It is recommended to request the server to determine the order status and not rely on this callback. This callback cannot guarantee that the order will definitely be paid successfully when called.
/// </summary>
/// <param name="order">Order information
/// The order object callback at the end of the payment flow. For details, see <see cref="Order"/>.
/// </param>
/// <param name="extra">Custom information defined by the developer</param>
public delegate void FinishType ( Order order, string extra );

public CancelType OnCancel { get; set; }
public ErrorType OnError { get; set; }
public FinishType OnFinish { get; set; }
}

Callback Callback<T>

/// <summary>  
/// Callback interface for asynchronous callback results of related functions. Supported functions are:
/// <ul>
/// <li><see cref="QueryItems(string,string[],Callback{TapTap.TapPay.bean.Item[]})"/></li>
/// <li><see cref="QueryItems(string[],Callback{TapTap.TapPay.bean.Item[]})"/></li>
/// <li><see cref="QueryOrder"/></li>
/// <li><see cref="ConsumeOrder(string,string,Callback{TapTap.TapPay.bean.Order})"/></li>
/// <li><see cref="ConsumeOrder(Order,Callback{TapTap.TapPay.bean.Order})"/></li>
/// </ul>
/// </summary>
/// <typeparam name="T">Generic parameter of callback result type</typeparam>
public class Callback < T >
{
/// <summary>
/// Request error
/// </summary>
/// <param name="error">Error
/// The error information for any occurred error. For details, see <see cref="Error"/>.
/// </param>
public delegate void ErrorType ( Error error );

/// <summary>
/// Request result
/// </summary>
/// <param name="result">Result</param>
public delegate void FinishType ( T result );

public ErrorType OnError { get; set; }
public FinishType OnFinish { get; set; }
}

Internationalization support

Language code list

Use the two-letter lowercase language codes defined in ISO 639-1 (for example, en indicates English, jp indicates Japanese). Note that:

  • Due to historical reasons in the Android system, use in instead of id for Indonesian.
  • When language codes alone cannot indicate the required language, add the region code defined in ISO 3166-1 (for example, zh_CN indicates Simplified Chinese).

Internationalization support has been provided for 8 languages, and the language codes are as follows:

CodeLanguage
enEnglish
zh_CNSimplified Chinese
zh_TWTraditional Chinese
inIndonesian
jaJapanese
koKorean
pt_BRBrazilian Portuguese
thThai

In addition, when setting item names in the DC backend, multi-language is also supported. The language parameters will affect the returned corresponding internationalized item name.

Default language

If no matching language is found, English will be used as the default language.