It is most suitable when the Gate Pay payment function is enabled in the merchants’ mobile APP.
After the merchant’s APP requests the SDK provided by Gate Pay to enable the Gate Pay payment function, the merchant APP’s page will jump to the Gate APP to complete the payment, and then jump back to the merchant’s APP interface once the payment is done, with the payment result displayed.
The function is currently available for IOS (Apple) and Android (Android) operating systems.
The interaction process is as follows:
Step 1: On the merchant’s APP, the users place an order, and confirm the purchase. After the payment process is started, a payment order will be created on the merchant’s service background. After being signed, the payment order will be transmitted to the APP.
Step 2: The users click to enter Gate’s payment interface, where they can request the Gate Pay payment. After the request is made, they will be directed to the page where confirmation of the payment is required.
Step 3: The users need to verify the payee and the payment amount, click “Pay”, and enter the password.
Step 4: The payment is completed once the correct password is provided. The payment result will be displayed on the page.
Step 5: Then the users will jump back to the merchant APP’s interface where the payment result will also be displayed in a manner set by the merchant.
The following is the sequence diagram of the interaction process. A signature is required for the order API, payment result notification API, and order query API, and the calls must be completed on the merchant server. The details are shown below.
Call payment runnning process:
Steps 1-6:
After the user initiates the payment, the merchant calls the GatePay order(/v1/pay/order
)API to create a prepayment order.
After the merchant calls the order API, the merchant will operate according to the contents returned.
Normal return: prepay_id
is returned, meaning the prepaid order is successfully created.
Abnormal return: http code or error code will be returned. The error code will indicate the cause and the next line of operations.
Steps 6-14:
Situation 1: If the merchant successfully obtains the prepayment order ID after the order interface is called, and at the same time the parameters and signature required to call the payment component interface are returned to the merchant’s APP, the merchant APP can directly call the payment component interface.
Situation 2: Step 6: If the prepayment order ID is returned to the merchant’s App without the calling parameters and signature, the merchant server side needs to provide an interface for obtaining the signature, and the merchant client side needs to request the merchant backend to provide it.
When the signature verification for calling the payment component is returned, the SDK pops up the payment component and calls to query the order information.
Steps 15-17:
After the user completes the payment, the payment result will be pushed to the client synchronously. Merchants can query the order status in the following two ways:
Method 1: Notification. After the user completes the payment, GatePay will synchronize the payment result with the merchant in the form of a callback notification. The merchant should provide the callback address as a part of the notify_url parameter when calling the APP order API.
Method 2: When the callback notification cannot be received due to network jitter or issues with the notify_url itself, the merchant can call the query order API (/v1/pay/order/query) to query the order status.
In order to synchronize order information with merchants, GatePay provides a query interface enabling the merchants to query prepaid orders and refund orders.
JSON (content-type: application/json)
POST
/v1/pay/open/sdk
body type:
Parameter Name | Variable | Type | Required | Description |
---|---|---|---|---|
Application ID | clientid | string | Yes | The mobile app ID approved by Gate Open Platform |
Merchant Number | merchantid | string | Yes | Merchant number |
Pre-order ID | prepayid | string | Yes | Pre-order ID |
Order Detail String | package | string | Yes | Fill in the fixed value GatePay for now |
Example of request:
curl --location --request POST 'https://openplatform.gateapi.io/v1/pay/open/sdk' \
--header 'Content-Type: application/json' \
--header 'X-GatePay-Certificate-ClientId: zb6WUrBDZlRAT7qz' \
--header 'X-GatePay-Timestamp: 1674117221032' \
--header 'x-GatePay-Nonce: 7436636664' \
--header 'x-GatePay-Signature: 11e658cf6b09d917caf9d4bb6ec4493431c55f066a694e58a5571a4a1a114ebc2011d346f340e54a5a2e2edaa172e907742fbdc99b94d009dade4b551daabd07' \
--data-raw '{"prepayid":"50620368071692288","package_ext":"ext"}'
success response:
{
"status":"SUCCESS",
"code":"000000",
"errorMessage":"",
"data":{
"prepayid":"50620368071692288"
}
}
failed response:
{
"status":"FAIL",
"code":"10002",
"errorMessage":"",
"data":{}
}
In order to synchronize order information with merchants, GatePay provides a query interface enabling the merchants to query prepaid orders and refund orders.
JSON (content-type: json)
POST
/v1/pay/order/query
request body type:
Attribute Name | Type | Required | Description |
---|---|---|---|
prepayId | string | No | Prepayment information. Either prepayId or merchantTradeNo must be provided. |
merchantTradeNo | string | No | Merchant order ID. Either prepayId or merchantTradeNo must be provided. |
response type:
Property Name | Type | Required | Description |
---|---|---|---|
status | string (SUCCESS or FAIL) | Yes | Payment status |
code | string | Yes | Error code |
data | query order return type | No | Payment order information |
errorMessage | string | No | Error message |
query order return type:
Property Name | Type | Required | Description |
---|---|---|---|
prepayId | string | Yes | The prepay ID. |
merchantId | int64 | Yes | Gate UID used to apply for a merchant account. |
merchantTradeNo | string | Yes | The merchant order number. |
transactionId | string | Yes | The transaction ID. |
goodsName | string | Yes | The name of the goods. |
currency | string | Yes | The currency of the order. |
orderAmount | string | Yes | The amount of the order. |
status | string | Yes | The status of the order. PENDING - Order pending payment, PROCESS - Payment processing, PAID - Payment succeeded, EXPIRED - Order expired, CANCELLED - Order cancelled by merchant, ERROR - Payment failed due to error. |
createTime | int64 | Yes | The timestamp when the prepay was created (in milliseconds). |
expireTime | int64 | Yes | The timestamp when the prepay will expire (in milliseconds). |
transactTime | int64 | Yes | The timestamp when the payment was completed (in milliseconds). |
order_name | string | Yes | The name of the order. |
pay_currency | string | Yes | The currency used for payment. |
pay_amount | string | Yes | The amount paid by the user. |
expectCurrency | string | No | The revenue currency specified by the merchant when creating the order. Only returned in details of orders with a specified settlement currency. |
actualCurrency | string | No | The actual currency used by Gate for settlement to the merchant after payment. Only returned after settlement. |
actualAmount | string | No | The actual amount settled by Gate to the merchant after payment. Only returned after settlement. |
rate | string | Yes | The exchange rate used for flash payment. |
channelId | string | No | Client Name. |
Example of request:
curl --location '127.0.0.1:8201/v1/pay/order/query' \
--header 'Content-Type: application/json' \
--header 'X-GatePay-Certificate-ClientId: zb6WUrBDZlRAT7qz' \
--header 'X-GatePay-Timestamp: 1678442053228' \
--header 'x-GatePay-Nonce: 2002257450' \
--header 'x-GatePay-Signature: ce9ed61041a3a76d292c7475e3957d2e788dd21e7e8b6aa523867a047892e4395a0dfd0e851e9a357a3582babe6a02e40ccff8111ee86d317cf56838f0b5568c' \
--data '{
"prepayId": "56416503889661952"
}'
Example of response:
{
"status": "SUCCESS",
"code": "000000",
"errorMessage": "",
"data": {
"prepayId": "56335302571069440",
"merchantId": 10002,
"merchantTradeNo": "118223456798",
"transactionId": "",
"goodsName": "NF2T",
"currency": "USDT",
"orderAmount": "1.9",
"status": "EXPIRED",
"createTime": 1675392982792,
"expireTime": 1675396480000,
"transactTime": 0,
"order_name": "MiniApp-Payment#118223456798",
"pay_currency": "",
"pay_amount": "0",
"expectCurrency": "BTC",
"rate": "0",
"channelId": "123456"
}
}
When the status of the prepaid order changes, such as expiration of the order due to exhaustion of payment time or successful payment of the order, the GatePay background will send a notification to the merchant to the notification address, which is the callback url provided by the merchant at registration.
If the notification fails to be sent to the merchant due to a network issue or other unknown reasons, GatePay background will resend it every 3 seconds, 10 times at most until it is sent successfully. If it still does not work, the merchant can query the status of the prepaid order by querying API.
JSON (content-type: application/json)
POST
Attribute | Type | Required | Description |
---|---|---|---|
bizType | string | Yes | The type of the business, must be "PAY". |
bizId | string | Yes | The ID of the prepayment. |
bizStatus | string | Yes | The status of the business, can be "PAY_SUCCESS" or "PAY_CLOSED". |
data | string | Yes | The JSON format string of the order data type object. |
order data types
Property Name | Type | Required | Description |
---|---|---|---|
merchantTradeNo | string | Yes | The merchant order ID |
goodsName | string | Yes | The name of the goods |
terminalType | string | Yes | The transaction source, for example, "MINIAPP" |
currency | string | Yes | The order currency |
orderAmount | string | Yes | The transaction amount |
payerId | int64 | No | The ID of the payer |
Example of request:
{
"bizType": "PAY",
"data": "{\"merchantTradeNo\":\"56236\", \"terminalType\":\"MINIAPP\", \"currency\":\"BTC\", \"orderAmount\":\"1.91\", \"payerId\":513301}",
"bizId": "1647557960944",
"bizStatus": "PAY_SUCCESS"
}
Example of response:
{
"returnCode": "SUCCESS",
"returnMessage": null
}
Cocoapods: pod 'GateOpen'
Info.plist
Configure the necessary parameters of Info.plist:
Add parameters of gate and gatepay to LSApplicationQueriesSchemes
@interface GOPayRequest : GORequest
///api_key provided by Gate
@property (nonatomic, copy) NSString *api_key;
///The UTC timestamp when the request was made
@property (nonatomic, copy) NSString *timestamp;
///Random string, the length of which had better not exceed 32 characters, and which should contain numbers and letters.
@property (nonatomic, copy) NSString *nonce;
///Request for signature
@property (nonatomic, copy) NSString *sign;
/// prepaid order ID
@property (nonatomic, copy) NSString *prepayid;
/// Jump back scheme such as: scheme://xxxx
/// If it is a deep link: <https://xxxx>
@property (nonatomic, copy) NSString *redirectUri;
@end
GateOpenManager
GateOpenManager is used to initiate and receive class of payment request callbacks.
@interface GateOpenManager : NSObject
+ (instancetype)shared;
/// Call payment method
/// @ param payItem payment required parameters
/// @ param handle payment result callback
- (void)payment:(GOPayRequest *)payItem result:(PayResultHandle)handle;
/// appdelegate jump analysis
/// @param url delegate OpenURL
- (void)handle:(NSURL *)url;
@end
GOPayResponse
GOPayResponse is used to encapsulate the parameters for payment result.
/// The return class after payment is completed.
@interface GOPayResponse : GOResponse
/// Whether the payment is successful?
@property (nonatomic, assign) BOOL isSuccess;
/// Affiliated information
@property (nonatomic, strong) NSString * _Nullable message;
- (instancetype _Nonnull)initWith:(BOOL)isSuccess
message:(NSString * _Nullable)message;
@end
The third-party application needs to obtain payment request parameters from its own server, create a GOPayRequest object, and then submit a payment request to the payment SDK.
/// Create payment request parameters GOPayRequest
GOPayRequest *payRequest = [[GOPayRequest alloc] init];
payRequest.prepayid = @"prepayId";
payRequest.timestamp = @"timestamp"
payRequest.nonce = @"signature";
payRequest.sign = @"signature";
payRequest.api_key = @"api_key";
payRequest.redirectUri = @"schemes://";
/// 发起支付请求
[[GateOpenManager shared] payment:payRequest result:^(GOPayResponse * _Nullable response) {
wSelf.payResultInfo.text = response.isSuccess ? @"支付成功" : @"支付失败";
wSelf.payResultInfo.textColor = response.isSuccess ? UIColor.greenColor : UIColor.redColor;
}];
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
[[GateOpenManager shared] handle:url];
return YES;
}
<repos>
folder provided by Gate Pay into the project root directory, or into the local maven repository.Integrate the <repos>
folder provided by Gate Pay into the project root directory, or into the local maven repository
allprojects {
repositories {
maven {
url uri("${rootProject.projectDir}/repos")
}
}
}
Add the following into the dependencies of the app module's build.gradle file
implementation 'com.gateio.sdk:gatepay-sdk:1.0.0'
Parameters Description:
Parameter Name | Type | Required | Description |
---|---|---|---|
isDebug | boolean | No | Whether to enable debug mode (DO NOT enable on production version!!!) (You can filter log messages with "gate_pay_sdk" to get corresponding exception information.) |
context | Context | Yes | It is recommended to pass the Application Context. |
clientId | String | Yes | The clientId obtained from GatePay platform (i.e., the api_key provided by Gate). |
redirectUri | String | Yes | The scheme uri that the current application needs to callback (If the project has not implemented scheme redirection, you can try passing "gate_default_scheme", and gatepay-sdk will automatically obtain the current Activity to implement redirection). |
Note: None of the parameters can be null, otherwise the initialization will fail.
Initialize SDK in onCreate in Application:
GatePaySDK.init(boolean isDebug, final Context context, String clientId, String redirectUri)
Parameters Description:
Property Name | Type | Required | Description |
---|---|---|---|
activity | Activity | Yes | The current activity of the application. |
signature | String | Yes | The request signature. Gate Pay uses this signature to verify the legitimacy of the request. |
timesTamp | String | Yes | The UTC timestamp when the request was generated, in milliseconds. Please note that Gate Pay does not process requests with timestamps that differ more than 5 seconds from the time it received the request. |
nonce | String | Yes | A random string composed of numbers and letters that conforms to HTTP header specifications. It is recommended to keep the length of the string within 32 characters. |
prepayId | String | Yes | The prepay order ID obtained from the payment request. |
packageExt | String | Yes | The package extension field with a fixed value of "GatePay". |
navigationGatePayListener | NavigationGatePayListener | Yes | A listener to handle the success or failure of the payment request and perform the corresponding actions. |
Error code description:
onGateOpenFailed(int code, String errorMessage)
Note: For codes other than the above, you can directly check the errorMessage for the information, or check the corresponding connecting error code in the Gate Pay server.
Note: Repeated callbacks can be avoided with the GatePaySDK.gateResumePayResult() method. The logic has been cleared, and it can only be obtained once. If you need to print the Log or make other judgments, you can temporarily store the value after obtaining it.
Notes:
Code value in the callback
Code: 10005--- failed (constant value: GatePayConstant.MESSENGER_STATE_CODE_FAILED)
Code:10006---cancel (constant value: GatePayConstant.MESSENGER_STATE_CODE_FAILED_CANCEL_PAY)
Code:10010---success (constant value: GatePayConstant.MESSENGER_STATE_CODE_SUCCESS)
Note: If it is 10010--success, check the payment result in the background and then display it. Note that the result returned by the client is not conclusive evidence of the payment result. Rather, the payment notification received by the server or the result returned by the query API shall prevail.
Can't return to the app after filling in the redirectUri? Check AndroidManifest to see whether android:exported="true" is active for the current Activity (had better in the mode of android:launchMode="singleTask")
No response for calling the startGatePay method? Set isDebug to true during initialization, and filter by keyword the "gate_pay_sdk" through Logcat to view the corresponding exception prompt:
The causes might Include but not limited to the following:
- The SDK is not initialized
- The clientId is not filled in
- The redirectUri is not filled in
- The Gate App has not been installed yet (the SDK has redirected to download it.)
- The Gate App is not in the latest version [3.11.1+] (the SDK has popped reminders suggesting to update and download the latest version)
After prepaid order and signature information is obtained on the current page, call the Gate payment component through GatePaySDK.startGatePay.
GatePaySDK.startGatePay(Activity activity, String signature, String timesTamp, String nonce,
String prepayId, String packageExt, NavigationGatePayListener navigationGatePayListener)
Get GatePayConstant.INTENT_GATE_B_CLASS_PARAM, with the parameter in Json format, such as: {"code":10006,"state":"cancel"}
Method 1): Obtain it directly from onNewIntent
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null) {
String intentData = intent.getStringExtra(GatePayConstant.INTENT_GATE_B_CLASS_PARAM);
}
}
Method 2): Get it in onResume()
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
if (intent != null) {
String intentData = intent.getStringExtra(GatePayConstant.INTENT_GATE_B_CLASS_PARAM);
}
}
After receiving the platform information, Gate Pay will provide the third party with api_key and api_secret, of which the api_key is used to identify the identity, and the api_secret is used to request signatures. The api_secret must be properly stored, and the signature information can only be generated through the server.
Note: Refer to GatePayDemo to view the complete access process.