Chuyển đến nội dung chính

Tích hợp SDK

Tổng quan

Thanh toán App-to-app, hay còn gọi là phương thức thanh toán trực tiếp qua Zalopay, là một cách thuận tiện để thanh toán đơn hàng bằng điện thoại thông minh. Khi người dùng chọn thanh toán đơn hàng trên ứng dụng Đối tác bằng phương thức "Thanh toán Zalopay", ứng dụng Đối tác sẽ điều hướng đến ứng dụng Zalopay và Zalopay sẽ tiến hành thanh toán. Việc tích hợp này cho phép thanh toán dễ dàng và nhanh chóng, cung cấp cách tích hợp các chương trình khuyến mãi, giảm nhu cầu tiếp xúc vật lý hoặc tiền mặt nhưng vẫn đảm bảo tính bảo mật khi thanh toán giữa các ứng dụng.

Quy trình thanh toán

Ở các phần tiếp theo chúng tôi sẽ hướng dẫn bạn từng bước tích hợp Zalopay. Bạn có thể truy cập Github Repository của chúng tôi để tham khảo 4 ví dụ triển khai của chúng tôi (ứng dụng Android, ứng dụng iOS, ứng dụng React Native trên nền tảng Android/iOS và ứng dụng Flutter trên nền tảng Android/iOS).

Trước khi bắt đầu

Trước khi bạn bắt đầu, hãy đảm bảo các công việc sau được thực hiện để tích hợp suôn sẻ:

  • Đã đăng ký tài khoản người bán thành công và có được app_id, mac_key từ Merchant Portal.
  • Hiểu cách sử dụng và đặc điểm kỹ thuật của CreateOrder API và khái niệm về truyền dữ liệu an toàn.
  • Môi trường phát triển của bạn đáp ứng các phiên bản dưới đây:
    • Đối với nền tảng iOS:
      • Phiên bản XCode 14.1
      • Phiên bản Ruby 2.7.6
      • Phiên bản Swift 5.7.1
    • Đối với nền tảng Android:
      • Phiên bản Gradle 7.5
      • Phiên bản Android Gradle plugin 7.2.2
      • Phiên bản JDK tối thiểu 11.0.13
  • Tải xuống zpdk-swift-x.x.x.framework (dành cho iOS) và zpdk-release-vx.x.aar (dành cho Android) tại đây nhằm hỗ trợ tích hợp ứng dụng Đối tác với ứng dụng Zalopay.

Cách hoạt động

Luồng thanh toán như sau:

  1. Đối tác thêm Zalopay làm phương thức thanh toán trong ứng dụng của họ, đồng thời khởi tạo ZPDK framework với app_id được cung cấp (ZPDK hỗ trợ thay đổi app_id cho Đối tác sử dụng nhiều id cho nhiều ứng dụng).
  2. Người dùng lựa chọn Zalopay làm phương thức thanh toán rồi tiến hành thanh toán.
  3. Ứng dụng Đối tác gọi CreateOrder API để tạo đơn hàng thanh toán mới. Ứng dụng Đối tác sẽ nhận được zpTransToken trong response.
  4. Ứng dụng Đối tác gọi hàm payOrder của ZPDK framework, với zpTransToken nhận được ở bước 3 làm tham số.
  5. Ứng dụng Đối tác điều hướng đến màn hình tạo đơn hàng của ứng dụng Zalopay. Lưu ý: Đối tác nên xử lý ứng dụng của mình trong trường hợp người dùng chưa cài đặt ứng dụng Zalopay.
  6. Người dùng hoàn tất thanh toán trên ứng dụng Zalopay. Zalopay điều hướng quay lại ứng dụng Đối tác kèm theo response.
  7. Ứng dụng Đối tác xử lý response và hiển thị thông báo phù hợp cho người dùng.

Cụ thể, quy trình của chúng tôi như sau:

Tích hợp

Nền tảng iOS

Bước 1. Thêm và khởi tạo Zalopay SDK

  1. Thêm framework ZPDK.framework vào ứng dụng
  2. Thay đổi cấu hình để cho phép khởi tạo Zalopay từ ứng dụng, bằng cách thêm zalo, ZalopayZalopay.api.v2 vào key LSApplicationQueriesSchemes. Đồng thời thêm url scheme của ứng dụng Đối tác (merchant-deeplink trong ví dụ này) vào key CFBundleURLSchemes để hỗ trợ điều hướng giữa các ứng dụng:
Info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>zalo</string>
<string>Zalopay</string>
<string>Zalopay.api.v2</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>CFBundleURLSchemes</string>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>org.reactjs.native.example.demozpdk</string>
<key>CFBundleURLSchemes</key>
<array>
<string>merchant-deeplink</string>
</array>
</dict>
</array>
  1. Ở file AppDelegate, khởi tạo ZPDK để xử lý việc trao đổi dữ liệu giữa Zalopay và ứng dụng:
AppDelegate.swift
// Gọi lại hàm này bất cứ khi nào bạn muốn khởi tạo lại ZPDK để cho phép thanh toán bằng app_id khác
//UriScheme giống như merchant-deeplink được cấu hình trong Info.plist ở trên
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
ZalopaySDK.sharedInstance()?.initWithAppId(<appid>, uriScheme: "<merchant-deeplink>", environment: <ZPZPIEnvironment>)
return true
}

//Gọi ZPDK để xử lý việc trao đổi dữ liệu giữa Zalopay và ứng dụng. Gọi hàm này vì ZPDK hiện đang kiểm tra xem ứng dụng nguồn có phải là Ứng dụng Zalopay hay không.
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return ZalopaySDK.sharedInstance().application(app, open: url, sourceApplication:"vn.com.vng.Zalopay", annotation: nil)
}

Bước 2. Gọi chức năng Thanh toán

  1. Gọi CreateOrder API. Đối tác sẽ nhận được zpTransToken sau khi gọi API thành công.
  2. Gọi hàm Payment sử dụng zpTransToken ở trên:
PayOrder.swift
//Depend on where you handle ZPPaymentDelegate.
ZalopaySDK.sharedInstance()?.paymentDelegate = self

ZalopaySDK.sharedInstance()?.payOrder(zpTransToken.text)

Bước 3. Xử lý kết quả trả về

ZPDK sẽ điều hướng quay lại ứng dụng Đối tác kèm theo response. Ứng dụng Đối tác cần xử lý kết quả trả về bằng cách sử dụng 3 callback sau:

PayOrder.swift
func paymentDidSucceeded(_ transactionId: String!, zpTranstoken: String!, appTransId: String!) {
//Xử lý trường hợp thanh toán thành công
}

func paymentDidCanceled(_ zpTranstoken: String!, appTransId: String!) {
//Xử lý trường hợp người dùng từ chối thanh toán
}

func paymentDidError(_ errorCode: ZPPaymentErrorCode, zpTranstoken : String!, appTransId: String!) {
//Xử lý trường hợp thanh toán lỗi
}

Bước 4. Xử lý trường hợp người dùng chưa cài đặt Zalopay

Để xử lý trường hợp người dùng chưa cài đặt Zalopay, trong hàm callback paymentDidError kiểm tra xem errorCode trả về có bằng ZPPaymentErrorCode.appNotInstall hay không. Nếu có, hãy gọi các hàm navigateToStore của ZPDK:

PayOrder.swift
func paymentDidError(_ errorCode: ZPPaymentErrorCode, zpTranstoken : String!, appTransId: String!) {
if (errorCode == .appNotInstall) {
//Gọi hàm này để điều hướng đến tải ứng dụng Zalo trên AppStore
ZalopaySDK.sharedInstance()?.navigateToZaloStore();

//HOẶC gọi hàm này để điều hướng đến tải Ứng dụng Zalopay trên AppStore
ZalopaySDK.sharedInstance()?.navigateToZalopayStore();
return;
}
}

Nền tảng Android

Bước 1. Thêm và khởi tạo Zalopay SDK

  1. Trong Android Studio, chọn menu File -> New -> New module... -> Import .JAR/.AAR Package
  2. Chọn tệp zpdk-release-vx.x.aar, sau đó đặt tên cho module mới
  3. Kiểm tra xem bạn đã nhập module zpdk vào dự án của mình trong tệp build.gradle của thư mục ứng dụng chưa:
build.gradle (:app)
dependencies {
...
implementation(name:'zpdk-release-v3.1', ext:'aar')
}
  1. Thêm url scheme của ứng dụng Đối tác vào file AndroidManifest.xml:
AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="merchant-deeplink"
android:host="app" />
</intent-filter>
  1. Khởi tạo ZPDK ở hàm onCreate của Android Activity bạn muốn:
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
...
ZalopaySDK.init(<appID>, <Environment>);

//Khởi tạo lại ZPDK nếu bạn muốn thanh toán bằng AppID khác
ZalopaySDK.tearDown();
ZalopaySDK.init(<appID>, Environment);
}

Bước 2. Gọi chức năng Thanh toán

Sau khi gọi CreateOrder API thành công và nhận được zpTransToken, hãy gọi chức năng Thanh toán với zpTransToken đó::

PayOrder.kt
//Cần phải hứng sự kiện OnNewIntent vì Zalopay App sẽ gọi deeplink tới ứng dụng Đối tác
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
ZalopaySDK.getInstance().onResult(intent)
}

ZalopaySDK.getInstance().payOrder(<Activity>, <Token>!!, "<MerchantApp Deeplink>", object: PayOrderListener {
...
})

Bước 3. Xử lý kết quả trả về

Triển khai PayOrderListener và xử lý logic phù hợp với ứng dụng Đối tác trong các hàm tương ứng với trạng thái giao dịch: onPaymentSucceeded, onPaymentCanceled, onPaymentError

PayOrder.kt
ZalopaySDK.getInstance().payOrder(..., object: PayOrderListener {
override fun onPaymentCanceled(zpTransToken: String?, appTransID: String?) {
//Xử lý logic khi người dùng từ chối thanh toán
}
override fun onPaymentError(ZalopayErrorCode: ZalopayError?, zpTransToken: String?, appTransID: String?) {
//Xử lý logic khi thanh toán lỗi
}
override fun onPaymentSucceeded(transactionId: String, transToken: String, appTransID: String?) {
//Xử lý logic khi thanh toán thành công
}
})

Bước 4. Xử lý trường hợp người dùng chưa cài đặt Zalopay

Để xử lý trường hợp người dùng chưa cài đặt Zalopay, trong hàm onPaymentError của PayOrderListener, kiểm tra ZalopayError = ZalopayError.ZALO_PAY_NOT_INSTALLED (mã 1) và gọi những hàm của ZPDK để điều hướng đến Store:

PayOrder.kt
if (ZalopayError == ZalopayError.PAYMENT_APP_NOT_FOUND) {
ZalopaySDK.getInstance().navigateToZaloOnStore(getApplicationContext())
ZalopaySDK.getInstance().navigateToZalopayOnStore(getApplicationContext())
}

Ứng dụng React Native trên nền tảng iOS và Android

Bước 1. Thêm và khởi tạo Zalopay SDK

  1. Để tích hợp và khởi tạo ZPDK bằng React Native, chúng tôi thực hiện tương tự như ứng dụng iOSAndroid ở trên
  2. Dùng các lớp Bridge cần thiết ở phía iOS và Android để giao tiếp hiệu quả với phía React Native

Bước 2. Gọi chức năng Thanh toán

  1. Ở phía iOS và Android, xuất một method cho React Native để gọi hàm payOrder của ZPDK:
PayZaloBridge.m
RCT_EXPORT_METHOD(payOrder:
(NSString *)zpTransToken) {
[ZalopaySDK sharedInstance].paymentDelegate = self;
[[ZalopaySDK sharedInstance] payOrder:zpTransToken];
}
ZPModule.java
@ReactMethod
public void payOrder(String zpTransToken) {
Activity currentActivity = getCurrentActivity();
ZalopaySDK.getInstance().payOrder(currentActivity, zpTransToken, "demozpdk://app", payOrderListener);
}
  1. Ở phía React Native, sau khi gọi CreateOrder API thành công và nhận được zpTransToken, dùng native module PayZaloBridge và gọi phương thức payOrder của nó:
PayOrder.js
import { NativeModules } from 'react-native';
const { PayZaloBridge } = NativeModules;

function payOrder() {
var payZP = NativeModules.PayZaloBridge;
payZP.payOrder(token);
}

Bước 3. Xử lý kết quả trả về

  1. Ở phía iOS, khai báo một sự kiện để React Native đăng ký. Sau đó, với mỗi callback được gọi, hãy gửi sự kiện đó đến phía React Native với dữ liệu tương ứng:
PayZaloBridge.m
- (NSArray<NSString *> *)supportedEvents
{
return @[@"EventPayZalo"];
}

- (void)paymentDidSucceeded:(NSString *)transactionId
zpTranstoken:(NSString *)zpTranstoken
appTransId:(NSString *)appTransId {
[self sendEventWithName:@"EventPayZalo" body:@{@"returnCode": [NSString stringWithFormat:@"%ld", (long)1], @"transactionId":transactionId ? transactionId : @"", @"zpTranstoken": zpTranstoken ? zpTranstoken : @"", @"appTransId": appTransId ? appTransId : @""}];
}

- (void)paymentDidCanceled:(NSString *)zpTranstoken
appTransId:(NSString *)appTransId {
[self sendEventWithName:@"EventPayZalo" body:@{@"returnCode": [NSString stringWithFormat:@"%ld", (long)4], @"zpTranstoken":zpTranstoken ? zpTranstoken : @"", @"appTransId": appTransId ? appTransId : @""}];
}

- (void)paymentDidError:(ZPPaymentErrorCode)errorCode
zpTranstoken:(NSString *)zpTranstoken
appTransId:(NSString *)appTransId {
[self sendEventWithName:@"EventPayZalo" body:@{@"returnCode": [NSString stringWithFormat:@"%ld", (long)errorCode], @"zpTranstoken":zpTranstoken ? zpTranstoken : @"", @"appTransId":appTransId ? appTransId : @""}];
}
  1. Ở phía Android, khai báo một sự kiện để React Native đăng ký. Sau đó, với mỗi callback của payOrderListener được gọi, hãy gửi sự kiện đó đến phía React Native với dữ liệu tương ứng:
ZPModule.java
private ReactApplicationContext mReactContext;

private void sendEvent(ReactContext reactContext, String eventName, WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}

PayOrderListener payOrderListener = new PayOrderListener() {
@Override
public void onPaymentSucceeded(String transactionId, String transToken, String appTransID) {
//Xử lý trường hợp thanh toán thành công
WritableMap params = Arguments.createMap();
params.putString("transactionId", transactionId);
params.putString("transToken", transToken);
params.putString("appTransID", appTransID);
params.putString("returnCode", PAYMENTSUCCESS);
sendEvent(mReactContext, "EventPayZalo", params);
}

@Override
public void onPaymentCanceled(String transToken, String appTransID) {
//Xử lý trường hợp người dùng từ chối thanh toán
WritableMap params = Arguments.createMap();
params.putString("returnCode", PAYMENTCANCELED);
params.putString("zpTranstoken", transToken);
params.putString("appTransID", appTransID);
sendEvent(mReactContext, "EventPayZalo", params);
}

@Override
public void onPaymentError(ZalopayError ZalopayError, String transToken, String appTransID) {
//Xử lý trường hợp thanh toán lỗi
WritableMap params = Arguments.createMap();
params.putString("returnCode", PAYMENTFAILED);
params.putString("zpTranstoken", transToken);
params.putString("appTransID", appTransID);
sendEvent(mReactContext, "EventPayZalo", params);
}
};
  1. Tại phía React Native, đăng ký sự kiện được khai báo ở trên và xử lý phù hợp:
PayOrder.js
import { NativeModules, NativeEventEmitter } from 'react-native';
const { PayZaloBridge } = NativeModules;
const payZaloBridgeEmitter = new NativeEventEmitter(PayZaloBridge);

componentDidMount() {
this.subscription = payZaloBridgeEmitter.addListener(
'EventPayZalo',
(data) => {
if(data.returnCode === 1){
//Handle success case
} else{
//Handle other cases
}
}
);
}

componentWillUnmount() {
this.subscription.remove();
}

Bước 4. Xử lý trường hợp người dùng chưa cài đặt Zalopay

Chúng tôi xử lý tương tự như Bước 4 của ứng dụng iOSAndroid ở trên


Ứng dụng Flutter trên nền tảng iOS và Android

Bước 1. Thêm và khởi tạo Zalopay SDK

Để tích hợp và cấu hình ZPDK, chúng ta thực hiện tương tự như Bước 1 của ứng dụng iOSAndroid ở trên

Bước 2. Gọi chức năng Thanh toán

  1. Ở phía iOS, đăng ký Flutter Method Channel trong hàm application mà được sử dụng để khởi tạo ZPDK iOS:
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ...

let controller = window.rootViewController as? FlutterViewController
let nativeChannel = FlutterMethodChannel(name: "flutter.native/channelPayOrder",
binaryMessenger: controller!.binaryMessenger)
nativeChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
guard call.method == MethodNames.methodPayOrder else {
result(FlutterMethodNotImplemented)
return
}

let args = call.arguments as? [String: Any]
let _zptoken = args?["zptoken"] as? String

ZalopaySDK.sharedInstance()?.payOrder(_zptoken)
result("Processing...")
})
}
  1. Ở phía Android, dùng lớp MainActivity kế thừa lớp FlutterActivity. Override phương thức configureFlutterEngine để đăng ký Flutter method channel:
MainActivity.kt
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)

MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "flutter.native/channelPayOrder")
.setMethodCallHandler { call, result ->
if (call.method == "payOrder"){
val token = call.argument<String>("zptoken")
ZalopaySDK.getInstance().payOrder(this@MainActivity, token !!, "merchant-deeplink://app",object: PayOrderListener {
// ...
})
} else {
result.success("Method Not Implemented")
}
}
}
}
  1. Ở phía Flutter, tạo Flutter MethodChannel. Sau khi gọi CreateOrder API thành công và nhận được zpTransToken, hãy gọi hàm thanh toán với zpTransToken đó:
PayOrder.dart
static const MethodChannel platform = MethodChannel('flutter.native/channelPayOrder');
final String result = await platform.invokeMethod('payOrder', {"zptoken": zpToken});

Bước 3. Xử lý kết quả trả về

  1. Ở phía iOS, cấu hình phần xử lý Flutter Event channel. Sau đó, gửi kết quả thanh toán tới Flutter bằng cách triển khai các chức năng liên quan đến từng mã kết quả:
AppDelegate.swift
  // Khởi tạo FlutterEventChannel để xử lý các sự kiện
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ...
let eventPayOrderChannel = FlutterEventChannel(name: "flutter.native/eventPayOrder",
binaryMessenger: controller!.binaryMessenger)
eventPayOrderChannel.setStreamHandler(self)
}

// Gửi sự kiện tới Flutter qua FlutterEventSink
private var eventSink: FlutterEventSink?
func paymentDidSucceeded(_ transactionId: String!, zpTranstoken: String!, appTransId: String!) {
guard let eventSink = eventSink else {
return
}
eventSink(["errorCode": 1, "zpTranstoken": zpTranstoken, "transactionId": transactionId, "appTransId": appTransId])
}

func paymentDidCanceled(_ zpTranstoken: String!, appTransId: String!) {
guard let eventSink = eventSink else {
return
}
eventSink(["errorCode": 4, "zpTranstoken": zpTranstoken, "appTransId": appTransId])
}

func paymentDidError(_ errorCode: ZPPaymentErrorCode, zpTranstoken: String!, appTransId: String!) {
guard let eventSink = eventSink else {
return
}
eventSink(["errorCode": errorCode, "zpTranstoken": zpTranstoken, "appTransId": appTransId])
}
  1. Ở phía Android, cấu hình xử lý Flutter Event channel. Sau đó, gửi kết quả thanh toán tới Flutter bằng cách triển khai các chức năng liên quan đến từng mã kết quả:
MainActivity.kt
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
// ...

EventChannel(flutterEngine.dartExecutor.binaryMessenger, "flutter.native/eventPayOrder")
.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, eventSink: EventChannel.EventSink) {
_eventSink = eventSink;
}
})

MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channelPayOrder)
.setMethodCallHandler { call, result ->
if (call.method == "payOrder") {
val tagSuccess = "[OnPaymentSucceeded]"
val tagError = "[onPaymentError]"
val tagCanel = "[onPaymentCancel]"
val token = call.argument<String>("zptoken")

ZalopaySDK.getInstance().payOrder(this@MainActivity, token !!, "merchant-deeplink://app",object: PayOrderListener {
override fun onPaymentCanceled(zpTransToken: String?, appTransID: String?) {
_eventSink?.success(mapOf(
"errorCode" to PAYMENTCANCELED, // code = 4
"zpTranstoken" to zpTransToken,
"appTransId" to appTransID,
))
}

override fun onPaymentError(ZalopayErrorCode: ZalopayError?, zpTransToken: String?, appTransID: String?) {
_eventSink?.success(mapOf(
"errorCode" to PAYMENTERROR,
"zpTranstoken" to zpTransToken,
"appTransId" to appTransID,
))
}

override fun onPaymentSucceeded(transactionId: String, transToken: String, appTransID: String?) {
_eventSink?.success(mapOf(
"errorCode" to PAYMENTCOMPLETE, // code = 1
"zpTranstoken" to transToken,
"transactionId" to transactionId,
"appTransId" to appTransID,
))
}
})
} else {
result.success("Method Not Implemented")
}
}
}
  1. Ở phía Flutter, đăng ký kênh sự kiện được tạo ở phía iOS và Android, sau đó xử lý các sự kiện tương ứng với từng mã kết quả:
PayOrder.dart
const EventChannel eventChannel = EventChannel('flutter.native/eventPayOrder');

Future<void> subscribe() async {
eventChannel.receiveBroadcastStream().listen(
(data) {
var res = Map<String, dynamic>.from(data);
String message;
if (res["errorCode"] == 1) {
message = "Thanh toán thành công";
} else if (res["errorCode"] == 4) {
message = "User hủy thanh toán";
} else {
message = "Giao dịch thất bại";
}
resultCallback(message);
},
onError: (error) {
resultCallback(error.toString());
},
);
}

Bước 4. Xử lý trường hợp người dùng chưa cài đặt Zalopay

Chúng tôi xử lý tương tự như Bước 4 của ứng dụng iOSAndroid ở trên


Kiểu dữ liệu kết quả trả về của ZPDK

Trường hợp thanh toán thành công - Xử lý hàm paymentDidSucceeded()

Tên dữ liệuKiểu dữ liệuMô tả
transactionIdstringId của giao dịch hiện tại
zpTranstokenstringToken của đơn hàng hiện tại
appTransIdstringapp_trans_id của giao dịch hiện tại

Trường hợp thanh toán bị hủy - Xử lý hàm paymentDidCanceled()

Tên dữ liệuKiểu dữ liệuMô tả
zpTranstokenstringToken của đơn hàng hiện tại
appTransIdstringapp_trans_id của giao dịch hiện tại

Trường hợp người dùng hủy thanh toán - Xử lý hàm paymentDidError()

Tên dữ liệuKiểu dữ liệuMô tả
errorCodestringMã lỗi trả về, là một trong các giá trị: UNKNOWN, PAYMENT_APP_NOT_FOUND, INPUT_IS_INVALID, EMPTY_RESULT, FAIL
zpTranstokenstringToken của đơn hàng hiện tại
appTransIdstringapp_trans_id của giao dịch hiện tại

Xem thêm

Tiếp theo

  • Đã cài đặt xong? Hãy kiểm thử kết quả tích hợp.