Alipay+ DocsAlipay+ Docs

Alipay+ client SDK APIs and SPIs

This document introduces interfaces that are provided by Alipay+ client SDK.

1. Overview

This section describes the interfaces that are used in the interaction between Alipay+ SDK and Mobile Payment Partner APP.

1.1 API (Mobile Payment Partner APP -> Alipay+ SDK)

Interface name

Description

Required

init/initWithContext

Initialize the Alipay+ SDK. The interface name for Android is init and for iOS is initWithContext.

M

openACCenter

Open the Alipay+ Center, which is a mini program.

M

getPaymentCode

Retrieve the payment code for one time, which is a string returned by a callback and needs to be rendered by the Mobile Payment Partner independently. Required for the User-presented Mode Payment product.

O

decode

Use this interface to decode when the code is handled by Alipay+. Required for the Merchant-presented Mode Payment product.

O

clear

Use this interface to clear the user login information cached by SDK. This interface must be used when the user logs out. 

M

inquireQuote

Query the exchange rate between a pair of currency. The exchange rate returned by Alipay+ is only for reference.

O

signContract

Auto-debit Payment occurs when a user purchases the merchandise on the merchant platform and the merchant deducts the funds from the user account by the access token. To use this payment product, the merchant must obtain the user authorization in advance.

1.2 SPI (Alipay+ SDK -> Mobile Payment Partner APP)

Interface name

Description

Required

getAuthCode

Obtain OAuth authorization code.

M

showAuthPage

Display the authorization page for the user to confirm.

M

pay

Open Mobile Payment Partner payment URL for payment.

M

getOpenUserInfo

Obtain the user open information.

M

scan

Use this interface to allow the user to scan a QR code or barcode presented by the merchant or selected from the album with Mobile Payment Partner app, then return the code string to Alipay+ SDK.

M

open

Use this interface to open a scheme, through which the user can view the wanted content. See Android app links and iOS Universal links for details.

M

2.API

2.1 init/initWithContext

Use this interface to initialize the Alipay+ SDK and the mini program. The initialization takes little time and is suggested to be performed when the Mobile Payment Partner app is launched. The initialization result is returned to Mobile Payment Partner app by initCallback .

Note:

If you use Android Dynamic Delivery to deliver the mini program package, the initialization might fail because of network reasons. The operation is performed in the background. After the Android App Bundle for mini program is downloaded and the initialization is successful or failed, the initialization result is returned to Mobile Payment Partner app by initCallback.

Parameters

Item

Android type

iOS type

Length

Description

Required

application

@NonNull Application

/

/

The Android application object

M

initConfig

@NonNull InitConfig

IAPConnectInitConfig

/

The configuration for initializing Alipay+ SDK

M

initCallback

@Nullable

InitCallback

/

/

The callback of the initialization. Required for Android.

O

Returns

N/A

Sample for Android

Sample of the SDK initialization:

copy
InitConfig initConfig = new InitConfig();
// for your productron version, please use 'PROD'
initConfig.envType = "DEV";

IAPConnect.init(this, initConfig, new InitCallback() {
            @Override
            public void onSuccess() {
                // to open Alipay+ service center
                // IAPConnect.openACCenter();
            }

            @Override
            public void onFailure(String errorCode, String errorMessage) {
                Toast.makeText(MyApplication.get(),
                    "Initialize error, errorCode: " + errorCode + ", errorMessage: " + errorMessage,
                    Toast.LENGTH_LONG).show();
            }
        });

Sample of the SPI configuration:

copy
/**
 * Meta info associated to subclasses of the BaseService class
 */
@ServiceMetaInfo(
        serviceName = "aplus.service.xxx", //xxx = oauth, member, payment
        category = ServiceCategory.ACL,
        type = ServiceType.OAUTH //OAUTH, MEMBER, PAYMENT
)


//Application class for registration

@Override
public void onCreate() {
    super.onCreate();
    //...
    
    //Register an implementation, this is done by the wallet devs
    //This is just to demonstrate that the implementation is initialised and loaded
    WalletServiceManager.getInstance().registerService(MemberServiceProvider.class);
    WalletServiceManager.getInstance().registerService(PaymentServiceProvider.class);
    WalletServiceManager.getInstance().registerService(OAuthServiceProvider.class);
    WalletServiceManager.getInstance().registerService(OpenCapabilityServiceProvider.class);
    WalletServiceManager.getInstance().registerService(CodeServiceProvider.class);
    WalletServiceManager.getInstance().registerService(DeeplinkServiceProvider.class);
}

Sample for iOS

Sample of the SDK initialization:

copy
IAPConnectInitConfig *config = [IAPConnectInitConfig new];
config.envType = SANDBOX;
config.loadingImpl = [MockLoading new];
// set main app flag, to tell the server which app the request come from
config.sourcePlatform = @"KakaoTalk";
[IAPConnect initWithContext:config completion:^(NSString * _Nonnull errorCode, NSString * _Nonnull errorMessage, BOOL success) {
    if (success) {
            // to open Alipay+ service center
            // IAPConnect.openACCenter();
    }else{
            //error Logic: toast error Message;
    }
}];

Sample of the SPI configuration:

copy
// WalletAPI initialization
// during application setup 

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // register the api manager to wallet context
    IAPWalletContextManager.instance.serviceManager = IAPWalletAPIManager()
     
    // This meta info can be loaded in a invisible swift file to load the real data
    let IAPWalletPaymentServiceMetaInfo = IAPWalletBaseServiceProvider(
            type: IAPWalletServiceType(category: .acl, type: "payment"),
            name: NSStringFromClass(PaymentService.self))
        
    let IAPWalletOAuthServiceMetaInfo = IAPWalletBaseServiceProvider(
            type: IAPWalletServiceType(category: .acl, type: "oauth"),
            name: NSStringFromClass(OAuthService.self))
        
    let IAPWalletMemberServiceMetaInfo = IAPWalletBaseServiceProvider(
            type: IAPWalletServiceType(category: .acl, type: "account"),
            name: NSStringFromClass(MemberInfoService.self))
     
    let IAPWalletCodeServiceMetaInfo = IAPWalletBaseServiceProvider(
            type: IAPWalletServiceType(category: .foundation, type: "code"),
            name: NSStringFromClass(CodeService.self))
     
    let IAPWalletDeeplinkServiceMetaInfo = IAPWalletBaseServiceProvider(
            type: IAPWalletServiceType(category: .foundation, type: "deeplink"),
            name: NSStringFromClass(Deeplink.self))
        
    IAPWalletContextManager.instance.serviceManager?.registerServices(metaInfos: [
            IAPWalletPaymentServiceMetaInfo,
            IAPWalletOAuthServiceMetaInfo,
            IAPWalletMemberServiceMetaInfo,
            IAPWalletDeeplinkServiceMetaInfo,
            IAPWalletCodeServiceMetaInfo
        ])
        
    // do rest of the setup for app ...
    return true
}

2.2 openACCenter

Open the Alipay+ Center, which is a mini program.

Parameters

N/A

Returns

Android type

iOS type

Length

Description

Required

boolean

boolean

/

An indicator of whether the Alipay+ Center mini program is opened successfully

M

Sample for Android

copy

boolean result = IAPConnect.openACCenter();
if (result) {
	Log.d(TAG, "openACCenter success");
} else {
	Log.e(TAG, "openACCenter failed");
}

Sample for iOS

copy
   UIViewController *centerVc = [IAPConnect openACCenter];
    if (centerVc) {
        NSLog(@"open AC Center success");
        [self.navigationController pushViewController:centerVc animated:YES];
    }
    else
    {
        NSLog(@"open AC Center failed");
    }

2.3 getPaymentCode

Mobile Payment Partner app uses this interface to obtain the payment code from Alipay+ client SDK. The payment code is returned by paymentCodeListener.

Parameters

Name

Android type

iOS type

Length

Description

Required

region

@NonNull String

String

/

The region where the payment occurs such as CN. Contact your BD team for the list of supported regions.

M

paymentCodeListener

@NonNull IPaymentCodeListener

IAPConnectPaymentCodeListener

/

Listener for payment code. Called when the payment code is generated.

M

Returns

N/A

Sample for Android

copy
String region = "CN";
IPaymentCodeListener paymentCodeListener = new IPaymentCodeListener() {
    @Override
    public void onPaymentCodeUpdated(String paymentCode) {
        // handle the paymentCode
        // please to render the QR code and bar code in this callback
    }

    @Override
    public void onPaymentCodeUpdateFailed(Result result) {
        //handle the error code and error message
        // Display error information to user or try to refresh the payment code again
        Log.i(TAG, result.resultCode);
    }
};
IAPConnect.getPaymentCode(region, paymentCodeListener);

Sample for iOS

copy
[IAPConnect getPaymentCode:@"CN" paymentCodeListener:self];

- (void)onPaymentCodeUpdateFailed:(NSString *)resultCode resultMessage:(NSString *)resultMessage{
    //handle the error code and error message
    
}

- (void)onPaymentCodeUpdated:(NSString *)paymentCode{
    // handle the paymentCode
}

2.4 decode

Use this interface to decode the code, which might be an order code or a collection code, by Alipay+. The value of decodeParameter is returned from Alipay+ Server SDK, which is provided by Alipay+ and integrated with Mobile Payment Partner server.

Parameters

Item

Android type

iOS type

Length

Description

Required

context

@NonNull Context

/

/

The Android activity's context. Required only for Android.

M

decodeParameter

@NonNull DecodeParameter 

DecodeParameter

/

The parameters that are required in the decoding process. See DecodeParameter for details.

M

decodeCallback

@NonNull IDecodeCallback

decodeCallback 

/

The callback function of decode result

M

Returns

N/A

Sample for Android

copy
// handled by SDK if isAcCode is true
if (isAcCode){
    decode(context, codeValue, acDecodeConfig, new IDecodeCallback(){
        @Override
        public void onResult(Result result){
            Log.i(TAG, result.resultCode);
        }
        
        @Override
        public void showLoading() {
            // some SDK operation is time consuming, here to show loading dialog
            // or the other UI to remind user
        }

        @Override
        public void dismissLoading() {
            // dismiss the dialog or tips UI
        }
    });
} 
// handled by MPP if isAcCode is false
else {
    
}

Sample for iOS

copy
IAPConnectDecodeModel *model = [IAPConnectDecodeModel new];
    model.scene = fromScene;
    model.codeValue = codeValue;
    [[IAPConnectClient sharedInstance] decodeWithModel:model
                                        decodeCallback:^(IAPConnectDecodeResult *result) { 
                                          NSLog(@"resultCode:%@===resultMessage:%@",result.resultCode,result.resultMessage);
                                           }];


2.5 clear

Mobile Payment Partner app must use this interface to clear the login information that is cached by SDK when the user logs out. Some business errors might occur if this interface is not called when user logs out.

Parameters

N/A

Returns

N/A

Sample for Android

copy
IAPConnect.clear();

Sample for iOS

copy
[IAPConnect clear];

2.6 inquireQuote

Use this interface to query the exchange rate between a pair of currency. The exchange rate returned by Alipay+ is only for reference.

Parameters

Item

Android Type

iOS Type

Length

Description

quoteCurrency

@NonNull QuoteCurrency

IAPConnectQuoteCurrency

/

The currency pair of which the exchange rate is queried

callback

@NonNull InquireQuoteCallback

IAPConnectInquireQuoteCallback

/

The callback that is used to return the exchange rate to Mobile Payment Partner

Returns

N/A

Sample for Android

copy
QuoteCurrency quoteCurrency = new QuoteCurrency();
quoteCurrency.sellCurrency = "KRW";
quoteCurrency.buyCurrency = "JPY";
IAPConnect.inquireQuote(quoteCurrency, new InquireQuoteCallback() {
    	@Override
		public void onResult(@NonNull String resultCode, @Nullable ForeignExchangeQuote foreignExchangeQuote) {
            if (TextUtils.equals(resultCode, ResultCode.SUCCESS
                                && foreignExchangeRate != null) {
                // get the foreignExchangeQuote to display
            } else {
            	// handle the fail case
                Log.e(TAG, "fail to inquire quote, errorCode: " + resultCode);
            }
        }
});

Sample for iOS

copy
IAPConnectQuoteCurrency *quoteCurrency = [IAPConnectQuoteCurrency new];
quoteCurrency.sellCurrency = @"KRW";
quoteCurrency.buyCurrency = @"JPY";
    [IAPConnect inquireQuote:quoteCurrency quoteCallback:^(NSString * _Nonnull resultCode, IAPConnectForeignExchangeQuote * _Nonnull result) {
    if (([resultCode isEqualToString:kIAPACSUCCESS])) {
    	// get the foreignExchangeQuote to display
    } else {
    	// handle the fail case
    }
 }];

2.7 signContract

Description

Use this interface to initiate the user authorization request for the Auto Debit payments.

Parameters

Name

Android type

iOS type

Length

Description

request

@NonNull SignContractRequest

@NonNull SignContractRequest

/

The request model for the user authorization request.

callback

@NonNull AcCallback<AcBaseResult>

@NonNull AcCallback<AcBaseResult>

/

The callback from Alipay+ SDK to Mobile Payment Partner app when the user authorization is completed.

Returns

N/A

Sample for Android

copy
Uri data = getIntent().getData();
String source = data.getQueryParameter("source");
if ("AlipayConnect".equals(source)) {
    SignContractRequest request = new SignContractRequest();
    request.needCallback = data.getBooleanQueryParameter("needCallback", false);
    String bizContent = data.getQueryParameter("bizContent");
    request.bizContent = bizContent;
    if (TextUtils.isEmpty(bizContent)) {
        request.authUrl = data.toString();
    }
    IAPConnect.signContract(request, result -> {
            if (result.success) {
                Log.i(TAG, "sign contract is success.");
                return;
            }
            if (TextUtils.equals(result.errorCode, ResultCode.USER_CANCEL)) {
                Log.i(TAG, "sign contract is cancelacled by user.");
            } else {
                Log.i(TAG, "sign contract is failed, resultMessage: " + result.errorMessage);
            }
        });
} else {
    // it is not the sign contract requirement from Alipay+
}

Sample for iOS

copy
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        
        var data : Dictionary<String, String> = [:]
        var needCallback :Bool?
        var bizContent :String?
        var source :String?
        var authUrl :String?
        
        let urlcomp = URLComponents(url: url, resolvingAgainstBaseURL: false)
        if let items = urlcomp?.queryItems {
            for item in items {
                if item.name == "code" {
                    data["code"] = item.value ?? ""
                }
                
                if item.name == "merchantType" {
                    data["merchantType"] = item.value ?? ""
                }
                if item.name == "needCallback" {
                    needCallback = (item.value! as NSString).boolValue
                }
                if item.name == "bizContent" {
                    bizContent = item.value!
                }
                if item.name == "source" {
                    source = item.value!
                }
            }
        }
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "alipayconnect"), object: data)
        
        if (source == "AlipayConnect") {
            let signContractRequest = IAPGOLSignContractRequest()
            if bizContent?.count ?? 0 > 0 {
                signContractRequest.bizContent = bizContent
            } else {
                signContractRequest.authUrl = url.absoluteString

            }
                  signContractRequest.needCallback = needCallback ?? true
                  IAPGOLSignContract.signContract(signContractRequest) { (result) in
                    if result?.success ?? false {
                        SVProgressHUD.showSuccess(withStatus: "success")
                    } else {
                        SVProgressHUD.showError(withStatus: result?.errorCode)
                    }
            }
        }
        
        return true
    }

3. SPI

An optional context model exists across all SPI method signature, which provides context information for tracing request, retrieving relevant merchant and the Acquiring Partner (ACQP) information, and so on.

Context

Field

Description

source

MANDATORY String

Valid values are:

  • MiniProgram
  • AlipayConnect
  • InteractivePlatform

miniProgramInfo

OPTIONAL MiniprogramMetaData/IAPWalletMiniprogramMetaData

The mini program meta data information that is generated from Alipay+ mini program platform. This field is required for the payment scenarios in the mini program. 

extendInfo

OPTIONAL Map<String, String>/Dictionary

Extended information. The field is reserved for future use.

MiniprogramMetaData (Android)/IAPWalletMiniprogramMetaData (iOS)

Field

Description

appId

OPTIONAL String

The unique ID that is assigned by Alipay+ mini program platform to identify a mini program

merchantId

OPTIONAL String

The unique ID that is assigned by Alipay+ mini program platform to identify a merchant

deployVersion

OPTIONAL String

Deployment version

Example: 6.1.1712141809.54

name

OPTIONAL String

Mini program name

logo

OPTIONAL String

Logo URL

Example: http://www.avatar.com/logo.png

desc

OPTIONAL String

Description of the mini program

developerVersion

OPTIONAL String

Internal developement version

Example: 6.1.0

appType

OPTIONAL Int

App type. Valid values are:

  • 1: HTML offline package
  • 2: Mini program

acquirerId

OPTIONAL String

The unique ID that is assigned by Alipay+ to identify an ACQP

languages

OPTIONAL Map<String, Map<String, String>>/NSDictionary<NSString*, NSDictionary<NSString*, NSString*>>

Mini program information in different languages, which contains name, description, and logo.

Example:

{

    "en_US": {

       "name": "miniprogram",

       "description": "miniprogram desc",

       "logo": "usa.jpg"

     },

     "zh_CN": {

       "name": "小程序测试",

       "description": "小程序测试desc",

       "logo": "china.jpg"

     }

}

clientParams

OPTIONAL Map<String, String>/Dictionary

Currently the sub field of appSourceTag is contained, which describes the source category of the mini program. Valid values of appSourceTag are:

  • 1: Second party, which means Mobile Payment Partner's mini program.
  • 2: Third party, which means merchant's mini program that is onboarding into the Mobile Payment Partner app.

Example:

"clientParams": {

    "appSourceTag": 1

 },

publishStatus

OPTIONAL String

Status of the mini program. Valid values are:

  • PUBLISHED
  • SUSPENDED
  • REMOVED

authClientID

OPTIONAL String

The unique ID that is assigned by Alipay+ to identify an AuthClient

acParams

OPTIONAL Map<String, String>/Dictionary

Extended information. The field is reserved for future use.

3.1 getAuthCode

Description

Alipay+ client SDK uses this interface to obtain the authorization code.

Implement the interface according to the following method signature:

Signature

getAuthCode(String clientId,

Set<String> scopes,

OAuthCodeFlowType type,

Map<String,String> extendedInfo,

APIContext context,

Callback<OAuthResult> callback);

getAuthCode(String url,

OAuthCodeFlowType type,

Map<String,String> extendedInfo,

APIContext context,

Callback<OAuthResult> callback)

Parameters

Name

Android & iOS type

Length

Description

authResult

OAuthResult

/

The result of calling the getAuthCode interface. For more information about the scopes used, see authorization scopes.

authFlowType

AuthFlowType

/

The type of OAuth flow.

In Android system, valid values are:

  • STANDARD
  • ALIPAY_CONNECT
  • LOCAL_MINI_PROGRAM

In IOS system, valid values are:

  • Standard
  • AlipayConnect
  • LocalMiniProgram
Returns

N/A

Sample for Android

copy
/**
 * OAuth, implement the OAuthService class
 * Call the getAuthorizedCodes to check which grant is provided to a clientId, before
 * making requests to the associated services of <? extends BaseService>
 */

import com.alipay.ap.android.wallet.acl.base.Callback;
import com.alipay.ap.android.wallet.acl.oauth.OAuthResult;
import com.alipay.ap.android.wallet.acl.oauth.OAuthService;

import java.util.Set;

/**
 * @since 0.1.1
 */
public class OAuthServiceProvider implements OAuthService {
    
    /**
     * Called to trigger the wallet to start the OAuth process, which will return the Authorisation
     * Code
     *
     * @param clientId clientId
     * @param scopes scopes of the client's request, 
     *          reference here: https://yuque.antfin-inc.com/imobile-end/tva9vq/tvq2t9
     * @param oauthFlowType The type of OAuth flow [Standard, Alipay_connect, local_mini_program]
     * @param extendedInfo Support specific scenario for non-unified scenarios,
     *                     etc Alipay+ has need for clientAuthId
     * @param callback The callback on the result of the user's OAuth approval
     * @since 0.3.0
     */
    void getAuthCode(String clientId, Set<String> scopes, OAuthCodeFlowType oauthFlowType,
                     Map<String, String> extendedInfo, APIContext apContext, Callback<OAuthResult> callback) {
        
        OAuthResult authResult = new OAuthResult();

        //Implement the OAuth flow and retrieve the authToken
        //...

        callback.result(authResult);
    }
    
    /**
     * This method is invoked when some service starts OAuth flow by passing in a agreement url
     * which needs to be rendered and signed by the user
     *
     * @param url The agreement url to open and sign
     * @param oauthFlowType The type of OAuth flow [Standard, Alipay_connect, local_mini_program]
     * @param extendedInfo Support specific scenario for non-unified scenarios,
     *                     etc Alipay+ has need for clientAuthId
     * @param callback The callback on the result of the user's OAuth approval
     * @since 0.3.0
     */
    void getAuthCode(String url, OAuthCodeFlowType oauthFlowType, Map<String, String> extendedInfo
                     , APIContext apContext, Callback<OAuthResult> callback) {
        OAuthResult oAuthResult = new OAuthResult();
        
        //Decodes the URL, and perform OAuth permission grant
        
        callback.result(oAuthResult);
    }
}
    /*
     Possible Auth Scopes: https://globaltech.alipay.com/docs/GPP/wallet-api/wallet-api
     */

Sample for iOS

copy
final class OAuthService: IAPWalletOAuthServiceSignature {
    
    /*
     Possible Auth Scopes: https://globaltech.alipay.com/docs/GPP/wallet-api/wallet-api
    */
    
    /// This method is invoked when some service starts OAuth process from the wallet
    /// - Parameters:
    ///   - clientId: the cliend Id of the service registered from the
    ///   - scopes: the scopes the client plans to apply
    ///   - type: the type of the authCode grant flow, default as standard the API caller can also specify it as a .alipayConnect specific flow.
    ///   - extendedInfo: Extended info parameters for non standard authflow
    ///   - callback: callback which will be used to inform the service caller about the service result
    override func getAuthCode(clientId: String, 
                              scopes: Set<String>, 
                              type: IAPWalletOAuthCodeFlowType, 
                              extendedInfo: [String: String],
                              in context: IAPWalletAPIContext?,
                              callback: @escaping (IAPWalletOAuthResult) -> Void) {
        // 1. execute auth process
        // type: .standard -> only the clientId is needed to get the authCode.
        // type: .localMiniProgram / .alipayConnect -> need to pass both the clientId as well as the authClientId
        
        // 2. based on auth result, cache current authorized scopes under userId and clientId
        // the scopes are granted via step 1. from the PSP OAuth server
        updateScopes(clientId: "clientId", incrementedScopes: ["BASE_USER_INFO"], decrementedScopes: ["USER_INFO"])
        
        // 3. after the authcode has been retrieved (in an asynchronous loop), trigger the callback
        // ----> async remote call: {
        callback(IAPWalletOAuthResult(authCode: "${server-issued-authCode}",
                                      authState: "${server-issued-authState}",
                                      authErrorScopes: ["USER_INFO": "${failed reasons}"],
                                      authSuccessScopes: ["BASE_USER_INFO"]))
        // ----> async remote call: }

    }
    
    /// This method is invoked when some service starts OAuth flow by passing in a agreement url which needs to be
    /// rendered and signed by the user
    /// - Parameters:
    ///   - url: The aggreement url to open and sign
    ///   - type: the type of the authCode grant flow, default as standard the API caller can also specify it as a .alipayConnect specific flow.
    ///   - extendedInfo: Extended info parameters for non strandard authflow
    ///   - callback: callback which will be user to inform the service caller about the service result
    override func getAuthCode(url: String, 
                              type: IAPWalletOAuthCodeFlowType, 
                              extendedInfo: [String: String], 
                              in context: IAPWalletAPIContext?,
                              callback: @escaping (IAPWalletOAuthResult) -> Void) {
        // 1. open the webview via url, check whether the following params are presented in the url
        // type: .standard -> only the clientId is needed to get the authCode.
        // type: .localMiniProgram / .alipayConnect -> need to pass both the clientId as well as the authClientId
        
        // 2. detect the universal link/redirect link triggered by the webpage
        
        // 3. based on auth result, cache current authorized scopes under userId and clientId
        // the scopes are retrieved from step 2.
        updateScopes(clientId: "clientId", incrementedScopes: ["BASE_USER_INFO"], decrementedScopes: ["USER_INFO"])
        
        // 4. after the authcode has been retrieved (in an asynchronous loop), trigger the callback
        // ----> async remote call: {
        callback(IAPWalletOAuthResult(authCode: "${server-issued-authCode}",
                                      authState: "${server-issued-authState}",
                                      authErrorScopes: ["USER_INFO": "${failed reasons}"],
                                      authSuccessScopes: ["BASE_USER_INFO"]))
        // ----> async remote call: }
    }
    
    // Provide updateScopes for store authScope info at the point when OAuth success, 
    // and getScopes for retrieving previously granted authScopes of the specific user.
    
    func updateScopes(clientId: String, incrementedScopes: [String] = [], decrementedScopes: [String] = []) {
        let userId = "${current-user-id-in-app}"
        let key = String(format: "IAPWalletAuthScope-%@-%@", userId, clientId)
        let raw = UserDefaults.standard.array(forKey: key) as? [String] ?? []
        let currentScopes = Set(raw)
        UserDefaults.standard.set(currentScopes
            .union(incrementedScopes)
            .subtracting(decrementedScopes)
            .sorted(), forKey: key)
    }
    
    func getScopes(clientId: String) -> [String] {
        let userId = "${current-user-id-in-app}"
        let key = String(format: "IAPWalletAuthScope-%@-%@", userId, clientId)
        return UserDefaults.standard.array(forKey: key) as? [String] ?? []
    }
}
 

3.2 showAuthPage

Description

Display the authorization page for the user to confirm.

Implement the SPI according to the following method signature:

Signature

showAuthPage(clientId: String, name: String,

                          logo: String, scopes: Set<String>, extendedInfo: [String : String]? = nil,

                          in context: IAPWalletAPIContext?,

                          callback: @escaping (IAPWalletAuthPageConfirmResult) -> Void)

Parameters

Name

Android & iOS type

Length

Description

pageConfirmResult

AuthPageConfirmResult

/

The user authorization result for the auto-debit payment

Returns

N/A

Sample for Android

copy
/**
 * OAuth, implement the OAuthService class
 * Call the getAuthorizedCodes to check which grant is provided to a clientId, before
 * making requests to the associated services of <? extends BaseService>
 */

import com.alipay.ap.android.wallet.acl.base.Callback;
import com.alipay.ap.android.wallet.acl.oauth.OAuthResult;
import com.alipay.ap.android.wallet.acl.oauth.OAuthService;

import java.util.Set;

/**
 * @since 0.1.1
 */
public class OAuthServiceProvider implements OAuthService {
    

    /**
     * This method is invoked when some service starts OAuth flow by passing in a agreement url
     * which needs to be rendered and signed by the user
     *
     * @param clientId the clientId of the app which triggers the authpage
     * @param name the name of the app to be displayed in the auth page
     * @param logo the app's logo, in form of a valid http/https resource 'url' to a logo image
     * @param scopes: the auth scopes the app is applying for, refer to this reference here: https://yuque.antfin-inc.com/imobile-end/tva9vq/tvq2t9
     * @param extendedInfo Support specific scenario for non-unified scenarios,
     *                     etc Alipay+ has need for clientAuthId
     * @param callback The callback on the result of the user's OAuth approval
     * @since 0.3.1
     */
    public void showAuthPage(String clientId, String name, String logo, Set<String> scopes,
                      Map<String, String> extendedInfo, APIContext apContext, Callback<OAuthPageConfirmResult> callback) {
        
        //Generate the OAuth permission page as required.
        //UI design of the page is specific to PSP implementation.
        
        OAuthPageConfirmResult confirmResult = null;
        String referenceAgreementId = ${OAuth service returns a reference approval id}; //optional, can be null
        
        if(${user approved}) {//If success
            confirmResult = new OAuthPageConfirmResult(referenceAgreementId);
        } else { //If fail/error
            confirmResult = new OAuthPageConfirmResult(null);
            //Error handling reference
            //https://yuque.antfin-inc.com/global-integration-technology/hhc5bf/ez52pl#iHVrc
        }
        
        callback.result(confirmResult);
    }
}

 /*
   Possible Auth Scopes: https://globaltech.alipay.com/docs/GPP/wallet-api/wallet-api
 */

Sample for iOS

copy
import IAPWalletContext

final class OAuthService: IAPWalletOAuthServiceSignature {
    
    /// **Note: ** the following SPIs are not used by Ant SDKs
    /// consultAuthPage(authId: String, extendedInfo: [String : String] = [:], callback: @escaping (IAPWalletOAuthConsultResult) -> Void)
    /// consultAuthPage(clientId: String, scopes: Set<String>, extendedInfo: [String : String] = [:], callback: @escaping (IAPWalletOAuthConsultResult) -> Void)
    
    /// This API is triggered by some of the Ant SDK use cases, like local miniprogram to ask App for displaying an authPage.
    /// - Parameter clientId: the clientId of the app which triggers the authpage
    /// - Parameter name: the name of the app to be displayed in the auth page
    /// - Parameter logo: the app's logo, in form of `url`
    /// - Parameter scopes: the auth scopes the app is applying for, refer to this [link](https://yuque.antfin-inc.com/docs/share/8bfa2603-7d4e-4ef7-b4f3-11565bf763c1?#) for the complete list of scopes.
    /// - Parameter extendedInfo: the extra optional information which the app might require to display on the authPage, refer to this [link]() for complete list of optional params
    /// - Parameter callback: the async callback to inform whether the user abort or confirm the authPage. If error object is not nil in the service result, it means the user reject/aborts the authPage. 
    override func showAuthPage(clientId: String,
                               name: String,
                               logo: String,
                               scopes: Set<String>,
                               extendedInfo: [String : String]? = nil,
                               in context: IAPWalletAPIContext?,
                               callback: @escaping (IAPWalletAuthPageConfirmResult) -> Void) {
        // override the method to provide a authpage confirmation popover
        var scopeInfo = ""
        for scope in scopes {
            if (scope == OAuthService.SCOPE_BASE_USER_INFO) {
                scopeInfo += "- Access basic user information\n"
            } else if (scope == OAuthService.SCOPE_AGREEMENT_PAY) {
                scopeInfo += "- Conduct aggreement pay automatically\n"
            } else if (scope == OAuthService.SCOPE_USER_NAME) {
                scopeInfo += "- Access to user's real name\n"
            } else if (scope == OAuthService.SCOPE_USER_LOGIN_ID) {
                scopeInfo += "- Retrieve user login id in the app.\n"
            } // ... iterate through all possible scopes
        }
        
        let authPage = UIAlertController(title: "Authorisation Confirmation",
                                         message: "\(name) wants to access for the following information: \n\(scopeInfo)" ,
                                         preferredStyle: .alert)
        
        authPage.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Default action"),
                                         style: .default,
                                         handler: { _ in
                                            // 1. synchronize with wallet server regarding aggreement check
                                            // ----> async remote call: {
                                                ----- case 1 -----
                                                // 2.1 Option 1: when confirmation is purely checked offline
                                                // then inform the SDK that agreement has ben confirmed
                                                let result = IAPWalletAuthPageConfirmResult()
                                                callback(result)
                                                
                                                ----- case 2 ----- 
                                                // 2.2 Option 2: when confirmation is passed to server for ack
                                                // then inform the SDK with the agreementId from server
                                                let result = IAPWalletAuthPageConfirmResult("${agreementReferenceId}")
                                                callback(result)
                                            // ----> }
        }))
        
        authPage.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: "User reject"),
                                         style: .cancel,
                                         handler: { _ in
                                            
                                            // 1. if error is presented, the SDK will assume user abort the operation.
                                            let result = IAPWalletAuthPageConfirmResult()
                                            result.error = NSError(domain: "${psp-wallet-domain}",
                                                                   code: IAPWalletBaseServiceResult.ERROR_CODE_USER_CANCEL, // or any ${psp-wallet-domain-code}
                                                                   userInfo: [NSLocalizedDescriptionKey: "user canceled"])
                                            callback(result)
                                            
        }))
    }
    

    /*
     Possible Auth Scopes: https://globaltech.alipay.com/docs/GPP/wallet-api/wallet-api
     */
}

3.3 pay

Description

Alipay+ SDK uses this interface to open the Mobile Payment Partner payment page.

Implement the SPI according to the following method signature:

Signature

pay(with request: IAPWalletPaymentRequest,

                   in context: IAPWalletAPIContext?,

                   callback: (IAPWalletPaymentResult) -> Void)

Parameters

Name

Android & iOS type

Length

Description

paymentRequest

PaymentRequest

/

The request object to initiate a payment

paymentResult

PaymentResult

/

Payment result

Returns

N/A

Sample for Android

copy
public class PaymentServiceProvider implements PaymentService {
    
    /**
     * The method that is call for any payment request to bring up e.g. the cashier pay to fulfill
     * payment to the payment requestee
     * @param request The request object
     * @param callback The callback on the payment result, success/failures
     */
    @Override
    public void pay(PaymentRequest request, APIContext apContext, Callback<PaymentResult> callback) {
        PaymentResult paymentResult = new PaymentResult();
        
        //Implement logic to open the cashier page
        // e.g. With Griver, Griver.openUrl(...)
        //...
        
        //To handle callbacks - Griver-WAP typed
        // 1. Consider having a custom JSAPI that is able to passing payment status
        // to the native level, to callback to the Callback<PaymentResult> object
        // 2. Have the JSAPI implement observer pattern, to intercept requests specific
        // to payment result page closure, and register the Callback<PaymentResult> object
        // as an observer to it.
        
        //To handle callbacks - Native/Java typed
        // 1. Consider designing an observer pattern for your native cashier to observe for
        // Cashier result page closure e.g. activity.finish()
        // 2. And register the register the Callback<PaymentResult> object as observer
        
        callback.result(paymentResult);
    }
}

/*
 * Referring to payment codes from:
 * - Miniprogram : https://opendocs.alipay.com/mini/api/openapi-pay
 * provide a superset of the payment codes.
 */
//Payment: ACL standardized Result Codes
public static final String CODE_PENDING = "8000";
public static final String CODE_FAILURE = "4000";
public static final String CODE_SUCCESS = "9000";
public static final String CODE_USER_CANCEL = "6001";

Sample for iOS

copy
final class PaymentService: IAPWalletPaymentServiceSignature {
    
    /*
      Referring to payment codes from:
        - Alipay+ 2.0 : https://yuque.antfin-inc.com/docs/share/d2577213-2311-45b3-871a-670cceb64fcf?#TMqJ0
      provide a superset of the payment codes. This codes can be consumed by Miniprogram & Alipay+ directly
     */
    public static let CODE_PENDING = "8000" // PAY_PENDING
    public static let CODE_FAILURE = "4000" // PAY_FAILURE
    public static let CODE_SUCCESS = "9000" // PAY_SUCCESS
    public static let CODE_USER_CANCEL = "6001" // USER_CANCEL
    
    override func pay(with request: IAPWalletPaymentRequest, 
                      in context: IAPWalletAPIContext?,
                      callback: (IAPWalletPaymentResult) -> Void) -> Void {
        // Step 1. Check the payment type request parameters, which could be:
        //  - orderId: orderId
        //  - paymentId: paymentId
        //  - cashierUrl: cashier url to be rendered by web cashier
        //  - orderString: a string which contains complete order information. (in mini program case, this payment type is not currently used)
        
        // Step 2. Render cashier and conduct payment process
        
        // Step 3. Invoke callback to inform mini program about the payment result
        // result code please refer to the code const listed above the pay() method.
        // result message there is not strict limitation.
        // ----> async remote call: {
        callback(IAPWalletPaymentResult(resultCode: CODE_SUCCESS, resultMessage: "payment success"))
        // ----> async remote call: }
    }
}

@end

3.4 getOpenUserInfo

Description

Use this interface to obtain the open user information. When Mobile Payment Partner app obtains the information from Mobile Payment Partner server, the open user information is passed to Alipay+ SDK by userInfoCallback asynchronously.

Implement the SPI according to the following method signature:

Signature

getMemberInfo(strategy: IAPWalletMemberInfoFetchStrategy,

                      scope: IAPWalletMemberInfoScope?,

                      in context: IAPWalletAPIContext?,

                      callback: @escaping (IAPWalletMemberInfoFetchResult) -> Void)

Parameters

N/A

Returns

Name

iOS & Android type

Length

Description

memberInfo

MemberInfo

/

The object that contains the user information

memberInfoResult

MemberInfoResult

/

The callback for getMemberInfo(), which includes the payload of memberInfo

fetchStrategy

MemberInfoFetchStrategy

/

The strategy to fetch the user information suggested by Alipay+ Client SDK

memberInfoScope

MemberInfoScope

/

The user information scope

Sample for Android

copy
public interface MemberService extends BaseService {

    /**
     * Gets the current member info for this user
     *
     * @param fetchStrategy the strategy used to fetch user info, can be a
     * <br>userId only - {@link com.alipay.iap.android.wallet.acl.member.MemberService.MemberInfoFetchStrategy#LOCAL_USER_ID_ONLY},
     * <br>locally cached full memberInfo - {@link com.alipay.iap.android.wallet.acl.member.MemberService.MemberInfoFetchStrategy#LOCAL_CACHED}, or
     * <br>force to fetch from remote - {@link com.alipay.iap.android.wallet.acl.member.MemberService.MemberInfoFetchStrategy#REMOTE_FETCH}
     * <br><br>Depending on user info sensitivity, you may have to consider also to validate if the
     * related OAuth scope for MemberInfo has been granted via {@link com.alipay.iap.android.wallet.acl.oauth.OAuthService#getAuthorizedScopes(String, Map, APIContext, Callback)},
     * if not, you may have to request {@link com.alipay.iap.android.wallet.acl.oauth.OAuthService#getAuthCode(String, OAuthCodeFlowType, Map, APIContext, Callback)} first
     * @param memberInfoScope the scope of the member information should cover
     * @param apiContext The api context associated with this request {@link com.alipay.iap.android.wallet.acl.base.APIContext} - Optional, set as null if not used
     * @param memberInfoCallback callback returning the MemberInfoResult
     *
     * @version 0.4.1 added APIContext parameter in method signature
     */
    void getMemberInfo(MemberInfoFetchStrategy fetchStrategy, MemberInfoScope memberInfoScope, APIContext apiContext, Callback<MemberInfoResult> memberInfoCallback);

    /**
     * Defines the type of strategy to return the MemberInfo details
     */
    enum MemberInfoFetchStrategy {

        /**
         * Strategy to return only the userId
         * The MemberService.getMemberInfo(), should immediately invoke the callback
         * to simulate a synchronous response
         */
        LOCAL_USER_ID_ONLY,

        /**
         * Strategy to returns the locally cached MemberInfo
         * The MemberService.getMemberInfo(), should immediately invoke the callback
         * to simulate a synchronous response
         */
        LOCAL_CACHED,

        /**
         * Strategy to return the remote up to date MemberInfo
         * The MemberService.getMemberInfo(), this response can be asynchronously responded
         * based on network/remote response.
         */
        REMOTE_FETCH
    }

}

Sample for iOS

copy
final class MemberInfoService: IAPWalletMemberServiceSignature {
    
    override func getMemberInfo(strategy: IAPWalletMemberInfoFetchStrategy,
                                scope: IAPWalletMemberInfoScope?,
                                in context: IAPWalletAPIContext?,
                                callback: @escaping (IAPWalletMemberInfoFetchResult) -> Void) {
        
        if (strategy == .localCached) {
            
            // return the full amount of userInformation from local cache
            let memberInfo = IAPWalletMemberInfo(
                userId: "${user-id}",
                sessionId: "${session-id}",
                loginId: "${login-id}",
                gender: "m/f",
                avatar: "${avatar-url}",
                userName: "${user-name}")
            memberInfo.extendedInfo = [
                "nickName": "nick name of user",
                "countryCode": "65/86",
                "province": "xxx",
                "province": "xxx",
                                      ]
            // synchronized call
            callback(IAPWalletMemberInfoFetchResult(memberInfo: memberInfo))
            
        } else if (strategy == .localUserIdOnly) {
            
            // return user id only, this strategy is used when some of the SDK's internal logic wants
            // to get a user specified path for data storage
            let memberInfo = IAPWalletMemberInfo(userId: "${user-id}")
            
            // synchronized call
            callback(IAPWalletMemberInfoFetchResult(memberInfo: memberInfo))
            
        }
    }
}

3.5 scan

Description

Use this interface to allow the user to scan a QR code or barcode that is presented by the merchant or selected from the album with the Mobile Payment Partner app, then return the code string to Alipay+ SDK.

Implement the SPI according to the following method signature:

Signature

scan(with option: IAPWalletScannerOption,

                 in context: IAPWalletAPIContext?,

                 callback: @escaping (IAPWalletScannerResult) -> Void)

Paramters

Name

Android & IOS type

Length

Description

scannerOption

ScannerOption

/

The options that Mobile Payment Partner must provide for the user to scan the QR code/barcode. The options are:

  • Scanning the QR code/barcode presented by the merchant
  • Scanning the QR code/barcode in the picture that is selected from the album

scanResult

ScannerResult

/

The result collected from the scanned code

Returns

N/A

Sample for Android

copy
public class CodeServiceProvider implements CodeService {
    @Override
    public void scan(ScannerOption scannerOption, APIContext apContext, Callback<ScannerResult> scannerResultCallback) {
        ScannerResult scannerResult = new ScannerResult("xxxxcodexxxx");
        scannerResult.setExtendedInfo(null);
        scannerResult.getExtendedInfo();
        scannerResultCallback.result(scannerResult);
    }
}

Sample for iOS

copy
final class CodeService: IAPWalletCodeServiceSignature {
    
    // Mark: this API is currently used by Miniprogram combined with Alipay+ 2.0 case.
    override func scan(with option: IAPWalletScannerOption, 
                       in context: IAPWalletAPIContext?,
                       callback: @escaping (IAPWalletScannerResult) -> Void) {
        // open up your qrcode scanner in your app based on the following option:
        // option.type = .qrCode -> qrcode scanner
        // option.type = .barCode -> barcode scanner
        
        // invoke the callback to passback the result, this can be invoked asynchronously.
        // ----> async remote call: {
        callback(IAPWalletScannerResult(code: "${code extracted}"))
        // ----> async remote call: }
    }
}

3.6 open

3.6.1 open scheme

Description

Use this interface to open an in-app page of the destination scene or navigate to the destination scene across apps. See Android app links and iOS Universal links for details.

Implement the SPI according to the following method signature:

  • Android Signature

bool open(Uri scheme, APIContext apiContext)

  • iOS Signature
  • Swift Signatures

open(scheme: URL, in context: IAPWalletAPI.IAPWalletAPIContext? = nil) -> Bool

  • Objective-C signature

BOOL openScheme:(NSString *)url context:(APIContext *)apiContext

Parameters

Item

Android type

iOS type

Length

Description

scheme

Uri

NSString

Immutable URI reference. A URI reference includes a URI and a fragment. The component of the URI is followed by a number sign (#). Build and parse URI references which conform to RFC 2396.

Returns

Android type

iOS type

Length

Description

Required

boolean

boolean

/

An indicator of whether the scheme is opened successfully.

M

Sample for Android

copy
public class DeeplinkServiceProvider implements DeeplinkService {
    @Override
    public boolean open(Uri deepLink) {
        
        //Your operation to open this URI
        if(isAuthorised(deepLink)) {
            //Handles the deeplink either natively, or as webview
        } else {
            //Returns false if deeplink is not handled
            return false;
        }
        
        return true;
    }
}

Sample for iOS

copy
final class DeeplinkService: IAPWalletDeeplinkService {
    
    // Mark: this API is currently used by Miniprogram combined with Alipay+ 2.0 case.
    override func open(scheme: URL,
                       in context: IAPWalletAPIContext?) -> Bool {
        // the wallet app can choose to process the scheme as deeplink,
        // or ordinary url open in webview, the follow is returned synchronously
        if UIApplication.shared.canOpenURL(scheme) {
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(scheme, options: [:], completionHandler: nil)
                return true
            } else {
                UIApplication.shared.openURL(scheme)
                return true
            }
        } else {
            return false
        }
    }
}

3.6.2 open sceneCode

Description

Use this interface to open an in-app page of the destination scene or navigate to the destination scene across apps. See Android app links and iOS Universal links for details.

Implement the SPIs according to the following method signature:

  • Android Signature

open(@NonNull String sceneCode,

                   @NonNull Map<String, String> params,

                   @Nullable APIContext apiContext,

                   @NonNull Callback<BaseResult> openBizSceneCallback)

  • iOS Signatures
  • Swift Signature

open(bizSceneCode: String,

              with params: [String:String],

              in context: IAPWalletAPIContext? = nil,

              callback: @escaping (IAPWalletBaseServiceResult) -> Void)

  • Objective-C Signature

openBizSceneCode:(NSString *)sceneCode

                      params:(NSDictionary<NSString *, NSString *> *)params

                      context:(IAPWalletAPIContext *)context

   callback:(void(^)(IAPWalletBaseServiceResult *))callback;

Parameters

Item

Android type

iOS type

Length

Description

sceneCode

String

NSString

/

Scene code that presents a scene, such as SCAN and QR_CODE.

params

Map<String, String>

NSDictionary<NSString *, NSString *>

/

The parameters that the my.navigateToBizScene JSAPI provides, used for data transmission of this JSAPI. 

context

APIContext

IAPWalletAPIContext

/

The JSAPI context of mini programs.

Returns

Android type

iOS type

Length

Description

Required

void

void

/

An indicator of whether the scene code is opened successfully.

M

Sample for Android

copy
public class DeeplinkServiceProvider implements DeeplinkService {

    @Override
    public void open(@NonNull String sceneCode,
                     @NonNull Map<String, String> params,
                     @Nullable APIContext apiContext,
                     @NonNull Callback<BaseResult> openBizSceneCallback) {

        BaseResult baseResult = new BaseResult();
        baseResult.setExtendedInfo(params);
        try {
            // mock handle the navigate scene.
            if (sceneCode.contains("FAILURE")) {
                // mock fail callback
                baseResult.setResultError(new ResultError(
                        ResultError.ERROR_CODE_UNKNOWN_ERROR, "the is mock errorDesc in baseResult."));
            }
        }catch (Exception e) {
            Toast.makeText(MyApplication.get(), "openBizScene exception: " + e, Toast.LENGTH_LONG).show();
        }

        openBizSceneCallback.result(baseResult);
    }
}

Sample for iOS

copy
final class DeeplinkService: IAPWalletDeeplinkServiceSignature {
    
    // Mark: this API is designed for future AC-Combo use cases. currently not in use. developers may leave it empty.
    override func open(bizSceneCode: String, with params: [String:String], in context: IAPWalletAPIContext? = nil, callback: @escaping (IAPWalletBaseServiceResult) -> Void) {
        
        let result = IAPWalletBaseServiceResult()
        if (bizSceneCode == IAPWalletDeeplinkServiceSignature.SCENE_WEB_PAGE) {
            result.extendedInfo = ["${result-param-1-key}" : "${result-param-1-value}"]
            callback(result)
        } else if (bizSceneCode == IAPWalletDeeplinkServiceSignature.SCENE_SCAN) {
            result.extendedInfo = ["${result-param-1-key}" : "${result-param-1-value}"]
            callback(result)
        } else if (bizSceneCode == IAPWalletDeeplinkServiceSignature.SCENE_TOP_UP) {
            result.extendedInfo = ["${result-param-1-key}" : "${result-param-1-value}"]
            callback(result)
        }
        
        // implement all the relevant scene codes here.
    }
}

4. Appendix

This section describes the fields that are involved in the APIs and SPIs. If the interface names or class names are different for Android and iOS, the names are separated by a slash (/), of which the former one is for Android and the latter one is for iOS.

Authorization scopes

String

Scope

Description

AC

BASE_USER_INFO

Authorized to obtain the unique user ID

AGREEMENT_PAY

Authorized to use token to withhold user's assets

USER_INFO_FOR_CN

Authorized to obtain the information of user, including name, nationality, and birth date

USER_LOGIN_ID

Authorized to obtain the user login ID

HASH_LOGIN_ID

Authorized to obtain the hash user login ID

USER_NAME

Authorized to obtain the user name

MP

auth_user

Reserved for the payment scenario in the mini program

auth_base

Reserved for the payment scenario in the mini program

AuthPageConfirmResult

Item

Description

referenceAgreementId

The unique ID that is assigned by AuthClient to identify an authorization. This field is required when the user authorization for the auto-debit payment is successful.

ACConstants.Scene

public class Scene / enum Scene

Item

Type

Description

from_webview

String

The decode API is called in Mobile Payment Partner webview. Use ACConstants.Scene.SOURCE_FROM_WEBVIEW to obtain the string of from_webview for Android.

from_scan

String

The decode API is called in the scan page. Use ACConstants.Scene.SOURCE_FROM_SCAN to obtain the string of from_scan for Android.

from_other_app

String

The decode API is called by deep link from other apps. Use ACConstants.Scene.SOURCE_FROM_OTHER_APP to obtain the string of from_other_app for Android.

AcCallback

public interface AcCallback<T extends AcResult>

Return type

Method

Description

void

onResult(T t)

The interface that is used to return a specified result

AcBaseResult

public class AcBaseResult

Item

Type

Length

Description

Required

success

boolean

/

An indicator of whether the operation is successful

M

errorCode

String

/

The error code that is required when an error occurs

O

errorMessage

String

/

The error message that is required when an error occurs

O

bizContent

Item

Description

Required

acquirerId

The unique ID that is assigned by Alipay+ to identify an ACQP.

M

pspId

The unique ID that is assigned by Alipay+ to identify a Mobile Payment Partner

M

authClientId

The unique ID for AuthClient

M

authClientName

The AuthClient name for display

O

authClientLogo

The URL for Mobile Payment Partner to show the AuthClient logo

O

authRedirectUrl

The URL for Mobile Payment Partner to redirect the AuthClient to, provided by the AuthClient

O

scopes

Authorization scopes. For the auto-debit payment scenario, the value is AGREEMENT_PAY.

M

terminalType

The merchant terminal type. Valid values are:

  • WEB
  • WAP
  • APP
  • MINI_APP

M

referenceAgreementId

The unique ID that is assigned by AuthClient to identify an authorization

O

authState

Authorization statement that is generated by the AuthClient. When this field is provided, the value of this field must be appended to the redirectUrl to prevent the CRSF attack.

M

DecodeParameter

public class DecodeParameter / class IAPConnectDecodeModel

Item

Android Type

iOS Type

Description

scene

@NonNull String

Enum

Scenario of calling the decode API. Valid values are:

  • from_webview
  • from_scan
  • from_other_app

See ACConstants.Scene for details. The default value is from_scan.

codeValue

@NonNull String

NSString

Code value to be decoded by Alipay+

acDecodeConfigFromServer/decodeConfig

@NonNull String

NSString

The parameter received from Mobile Payment Partner server which is generated by Alipay+ Server SDK.

merchantType

@Nullable String

NSString

Merchant type. The parameter is required when the scene is Scene.SOURCE_FROM_OTHER_APP. The merchant type is usually passed by deep link, and the key in deep link is usually called ACAppType.

sourceAppPackageName

@Nullable String

null

The package name of merchant app. The parameter is required when the scene is Scene.SOURCE_FROM_OTHER_APP. The package name can be resolved from intent, or you pass the intent object of the deep link and Alipay+ SDK resolves the package name.

ForeignExchangeQuote

public class ForeignExchangeQuote / class IAPForeignExchangeQuote

Item

Type

Length

Description

Required

quoteId

String

64

The unique ID that is assigned by Alipay+ to identify a quote

M

quoteCurrencyPair

String

8

Exchange rate between a pair of currencies. Two currencies are separated with a slash and use the three-letter ISO-4217 currency code.

M

quotePrice

String

20

The exchange rate used when a currency conversion occurs

M

baseCurrency

String

3

The first currency in quoteCurrencyPair that is specified by the three-character ISO 4217 currency code

O

quoteUnit

String

12

The amount in baseCurrency

O

quoteStartTime

long

/

The date and time when quotePrice is effective. The time is UTC time in millisecond.

O

quoteExpiryTime

long

/

The date and time when quotePrice expires. The time is UTC time in millisecond.

O

InitConfig

public class InitConfig / class IAPConnectInitConfig

Item

Type

Description

Required

envType

String

The environment type of Mobile Payment Partner server. Valid values are:

  • PROD: production environment
  • DEV: development environment

The default value is PROD.

M

sourcePlatform

String

An identifier for the app, used to identify which app the request comes from.

M

userDelegate

Deprecated

UserDelegate

The collection of multiple interfaces that are used to obtain the user information from Issuing Participant. If Alipay+ Service Center (Combo) is integrated but the ACL SPIs are not used, this field is mandatory.

O

pay

Deprecated

IPay

The interface which is used to open the Issuing Participant payment page. If C-Scan-B Payment is integrated but the ACL SPIs are not used, this field is mandatory.

O

oAuth

Deprecated

IOAuth/IAPConnectOAuth

The interface that is used to obtain the authorization code. If the ACL SPIs are not used, this field is mandatory.

O

tid

String

The terminal ID of the current device. If the parameter is empty, SDK generates a terminal ID internally. If the value is tid, SDK uses the value directly. The length of tid cannot exceed 256, or unknown errors might occur.

O

userAgent

String

The user agent of Mobile Payment Partner. This parameter is required for Merchant-presented Mode Payment scenario.

O

InitCallback (only for Android)

public class InitCallback

Return type

Android method

iOS block method

Description

void

onSuccess

(void (^)(void))success

The callback when the initialization succeeds

void

onFailure(InitErrorCode initErrorCode, String errorMessage);

(void (^)(IAPConnectInitErrorCode errorCode,NSString *errorMessage))failure

The callback when the initialization fails. For more information about the failure reasons, see initErrorCode. The errorMessage field describes the failure in detail.

InitErrorCode

public enum InitErrorCode

Error code

Error message

INITIALIZE_UNKNOWN_EXCEPTION

Unknown exception occurs during the initialization. See errorMessage for details.

INITIALIZE_AUTHENTICATION_FAILED

Authentication of the mini program fails.

INITIALIZE_PARAM_ILLEGAL

Illegal parameters exist. For example, the application field or the initConfig field is null.

INITIALIZE_INVALID_NETWORK

The error only occurs when the mini program is provided by Android App Bundle. In this case, when Alipay+ SDK is initialized, Alipay+ SDK tries to download the Android App Bundle for mini program and then initialize the mini program.

IDecodeCallback/decodeCallback

public interface IDecodeCallback / decodeCallback:(void (^)(IAPConnectResult *result))decodeCallback

Return type

Android method

iOS block

Description

void

onResult(Result result)

void (^)(AlipayConnectResult *result)

The callback for decoding result

void

showLoading()

Null

Callback for showing loading dialog

void

dismissLoading()

Null

Callback for dismissing loading dialog

IPaymentCodeListener/ACPaymentCodeListenerDelegate

public interface IPaymentCodeListener / @protocol IAPConnectPaymentCodeListener <NSObject>

Return type

Method

Description

void

onPaymentCodeUpdated(@NonNull String paymentCode)

The callback used when payment code is updated

void

onPaymentCodeUpdateFailed(@NonNull String errorCode, @NonNull String errorMessage)

The callback used when some errors occur during the payment code update

IAPWalletPaymentAmount

Item

Type

Description

currency

String

The three-character ISO-4217 currency code

value

Int

The amount as a positive integer in the smallest currency unit (for example, if the value is 100, the amount is $1.00 when currency is USD, or ¥100 when currency is JPY)

IAPWalletPaymentType

Enum

Type

Description

orderId

Order ID

paymentId

Payment ID

orderStr

Detailed order information in a specified format, such as JSON, key-value pair, and so on

casherUrl

Cashier payment URL

IAPWalletCodeType

Enum

Type

Description

qrCode

QR code

barCode

Barcode

InquireQuoteCallback

public interface InquireQuoteCallback / foreignExchangeQuote: void (^)(ForeignExchangeQuote *result)

Return type

Android method

iOS block

Description

void

onResult(String resultCodeForeignExchangeQuote foreignExchangeQuote)

void (^)(String resultCodeForeignExchangeQuote *result)

The callback for exchange rate result

MemberInfo

Item

Description

userId

The user ID in the Mobile Payment Partner system

sessionId

Session ID

loginId

Login ID

loginIdTypeDeprecated

Login ID type. Valid values are:

  • email
  • mobile
  • index

avatar

HTTP URL of the image

gender

Gender. Valid values are:

  • m: Male
  • f: Female

birthday

Deprecated

The birthday that are expressed in UTC

userName

User name. Encrypting the value is allowed.

extendedInfo

Extended information in the set of key-value pairs. The following keys might be used:

  • nickName: Nick name. Encrypting the value is allowed.
  • countryCode: The two-character ISO 3166 country/region code
  • province: Province. Encrypting the value is allowed.
  • city: City. Encrypting the value is allowed.

See ExtendedInfo Use Cases for details.

MemberInfoFetchStrategy

Enum

Type

Description

LOCAL_USER_ID_ONLY

Obtain the locally cached user ID but payloaded into MemberInfo

LOCAL_CACHED

Obtain the locally cached MemberInfo

REMOTE_FETCH

Obtain the latest remote MemberInfo

MemberInfoScope

Item

Description

Required

appId

The ID of the app that calls the interface

O

scopes

The user information scopes. For more information about the scopes, see Authorization scopes.

O

OAuthResult

Item

Description

authCode

The authorization code 

that is generated by Mobile Payment Partner

authState

The authorization statement generated by the party that requests the authorization. This field is optional.

authErrorScopes

Scopes that are failed to be authorized

authSucessScopes

Scopes that are authorized successfully

PaymentRequest

Item

Type

Description

amount

IAPWalletPaymentAmount

Payment amount

type

IAPWalletPaymentType

Payment type. Valid values are:

  • orderId
  • paymentId
  • orderStr
  • casherUrl

paymentString

String

Payment string. The value is the same with that of type.

extendedInfo

Map<String, String>/Dictionary

Extended information in the set of key-value pairs. The possible key is paymentId. When the payment type is casherUrl, paymentId is provided in extendedInfo. See ExtendedInfo Use Cases for details.

PaymentResult

Item

Description

resultCode

Payment result code. See

Error codes

for details.

type

Payment result message

QuoteCurrency

public class QuoteCurrency / class IAPConnectQuoteCurrency

Item

Type

Length

Description

Required

sellCurrency

String

3

The currency that APS sells on behalf of the user and is specified by the three-character ISO 4217 currency code

M

buyCurrency

String

3

The currency that APS buys on behalf of the user and is specified by the three-character ISO 4217 currency code

M

Result/IAPConnectResult

public class Result / class IAPConnectResult

Item

Type

Description

resultCode

String

Result code. See

ResultCode

 for details.

resultMessage

String

Result message that describes resultCode in detail

merchantResultPageUrl

String

URL of the merchant result page starting with https

closeWebpage

boolean

An identifier of whether the web page is closed or not. The default value is true. If the merchantResultPageUrl in DecodeParameter is not empty, the value might be false.

ResultCode

public interface ResultCode / class IAPConnectManagerConstant <NSObject>

Name

ErrorMessage

Description

SUCCESS

success.

Operation is successful.

PROCESSING

The payment is in process.

The payment is in process.

PARAM_ILLEGAL

Oops! System busy. Try again later!

Illegal parameters exist. For example, a non-numeric input, or an invalid date.

INVALID_NETWORK

Oops! System busy. Try again later!

Network is invalid.

UNKNOWN_EXCEPTION

Oops! System busy. Try again later!

An API calling is failed, which is caused by unknown reasons.

PROCESS_TERMINATED

Oops! System busy. Try again later!

The process of MPM is terminated.

OTP_DUPLICATE_DECODE

Oops! System busy. Try again later!

Duplicate OTP decoding.

SERVICE_EXCEED_LIMIT

Oops! System busy. Try again later!

Service exceeds the limit.

PROCESS_FAIL

Oops! System busy. Try again later!

OAuth authorization is failed.

CLIENT_KEY_INVALID

Oops! System busy. Try again later!

Client key is invalid.

INVALID_SIGNATURE

Oops! System busy. Try again later!

Agreement sign signature verification is failed.

INVALID_CODE

Oops! System busy. Try again later!

Code value is invalid.

INVALID_AUTHCODE

Oops! System busy. Try again later!

Authorization code is invalid.

INVAILD_REDIRECTURL

Oops! System busy. Try again later!

Redirect URL is invalid.

SAL_FAIL_ICIF

Oops! System busy. Try again later!

Calling of ICIF (International Customer Core Service System) is failed.

EXPIRED_CODE

Oops! System busy. Try again later!

Payment code is expired.

USER_NOT_EXIST

Oops! System busy. Try again later!

User does not exist.

USER_STATUS_ABNORMAL

Abnormal account activity detached.

User status is abnormal.

REPEAT_REQ_INCONSISTENT

Oops! System busy. Try again later!

Repeated requests are inconsistent.

ORDER_NOT_EXIST

Oops! System busy. Try again later!

Order does not exist.

SDK_NOT_SUPPORT

Your app version is low, please upgrade to the latest version.

Your app version is low. Upgrade to the latest version.

EXPIRED_CODE

The payment code is expired, please refresh.

The payment code is expired. Refresh the code.

PAY_FAILURE

[The error message is from Mobile Payment Partner]

The payment is failed.

Note:

When Mobile Payment Partner performs the payment in the pay SPI and the payment fails, Mobile Payment Partner must send the error code PAY_FAILURE and error message to Alipay+ SDK.

ScannerOption

Item

Type

Description

type

IAPWalletPaymentAmount

Code type. Valid values are:

  • qrCode: QR code
  • barCode: Barcode 

hideAlbum

String

An indicator of whether the user scans a QR code/barcode in the picture selected from the album.

  • When the value is true, the user can use the camera to scan a QR code or barcode presented by the merchant, or select a barcode or QR code from the album to scan.
  • When the value is false, the user only can use the camera to scan the QR code or barcode presented by the merchant.

extendedInfo

String

This field is reserved for future use

ScannerResult

Item

Type

Description

code

String

The code value extracted by the scanner. This field is empty if some errors occur during scanning.

SignContractRequest

public class SignContractRequest / class IAPConnectSignContractRequest

Item

Type

Length

Description

Required

bizContent

String

/

The business content for the user authorization, which is generated by Alipay+. See bizContent for details. This field is mandatory when authUrl is empty.

O

authUrl

String 

/

The URL of the authorization page that is generated by the Mobile Payment Partner server and used by the Mobile Payment Partner app. This field is mandatory when bizContent is empty.

O

needCallback

boolean

/

An indicator of whether Alipay+ SDK sends the obtained authorization code to Alipay+ server. 

  • false: The merchant uses authCode to apply for the access token. Alipay+ SDK does not need to send the obtained authCode to Alipay+ server.
  • true: The merchant uses referenceAgreementId to apply for the access token. Alipay+ SDK sends the obtained authCode to Alipay+ to map the received referenceAgreementId from the merchant.

M