Integrate Native SPIs
Native SPIs are a set of interfaces that bridge the interaction between the Super App and mini programs. When mini programs make requests via certain JSAPIs, IAPMiniProgram SDK calls the corresponding Native SPIs to direct the request to the super appSuper App. By integrating these SPIs, the Super App grants mini programs the following services/capabilities:
- Obtaining user authorization
- Accessing user information
- Processing payments
- Scanning QR codes and barcodes
This topic mainly explains the function of each Native SPI and guides the Super App to integrate these SPIs step by step.
Overview
Native SPI | Associated JSAPI | Description |
OAuthService | The Super App integrates this SPI to provide authorization codes for mini programs. The mechanism is based on OAuth 2.0 standards and enables mini programs to securely access the resources or capabilities for proper functioning. For more information, refer to the following sections. | |
MemberService | The Super App integrates this SPI to provide basic user information for both mini programs and IAPMiniProgram SDK. This integration is important for the following use cases:
For more information, refer to the following sections. | |
PaymentService | The Super App integrates this SPI to enable mini programs to process payments. For more information, refer to the following sections. | |
CodeService | The Super App integrates this SPI to enable mini programs to use your scanner to scan QR codes or barcodes. For more information, refer to the following sections. |
Note:
- Calling a JSAPI triggers to call its associated Native SPI. Errors occur when the SPI fails to call.
OAuthService
This section explains the workflow and integration process of the OAuthService interface, which requests the Super App to generate authorization codes for the mini program.
Workflow
Procedures
Follow the procedure to integrate the OAuthService interface:
Step 1: Implement OAuthService
Create a class that implements the OAuthService interface. Within this class, sequentially implement the following methods: getAuthCode
, showAuthPage
, and getAuthorizedScopes
.
For the complete code samples, see Samples (in Swift).
Implement the getAuthCode
method
Call the getAuthCode
method to request the Super App to generate authorization codes for the mini program, and handle the following outcomes of the OAuth authentication flow:
- The user's consent is required before granting the mini program access to the requested scopes.
- The OAuth process succeeds.
- The OAuth process fails.
Implement the showAuthPage
method
Implement the showAuthPage
method to show the user authorization dialog and handle the following outcomes:
- The user allows mini program to access the requested scopes.
- The user declines or cancels the permission request.
Note: If the user allows mini program to access the requested scopes, the Super App needs to save the scopes to prevent the authorization dialog from reappearing when the same scopes are requested again. To save the scopes, the Super App can use the following caching logic:
func updateCachedScopesForUser(userId: String, appId: String, scopes: Set<String>) {
let cacheKey = getCacheKey(for: userId, appId: appId)
guard let currentScopes = getCachedScopesForUser(userId: userId, appId: appId) else {
defaults.set(Array(newScopes), forKey: cacheKey)
return
}
let updatedScopes = currentScopes.union(newScopes)
defaults.set(Array(updatedScopes), forKey: cacheKey)
}
private func getCacheKey(for userId: String, appId: String) -> String {
return "MPS_scope_\(userId)_\(appId)"
}
When caching the scopes, construct a unique key by combining appId (the mini-program ID), authClientId (the super app ID), and scope for identification, and set the value as a simple boolean true
to indicate that the scopes are granted.
Implement the getAuthorizedScopes
method
Implement the getAuthorizedScopes
method to retrieve a list of the authorized scopes.
Step 2: Register OAuthService to SDK
Before the SDK initialization logic, call the registerServices API to register the OAuthService interface to IAPMiniProgram SDK.
Refer to the following sample code for the registration:
import UIKit
import IAPConnect
import GRVAppContainer
import IAPWalletAPI
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
let window: UIWindow = {
let tmp = UIWindow(frame: UIScreen.main.bounds)
tmp.backgroundColor = .white
return tmp
}()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let homeViewController = HomeViewController()
let navigationController = UINavigationController(rootViewController: homeViewController)
window.rootViewController = navigationController
window.makeKeyAndVisible()
registerWalletServices()
setupMiniProgramSDK()
return true
}
func setupMiniProgramSDK() {
let config = IAPConnectInitConfig()
config.riverConfiguration = createConfiguration()
config.riverExtensionDelegate = createExtensionDelegate()
IAPConnectClient.sharedInstance().initWithContext(config) {
debugPrint("init success")
} failure: { code, message in
debugPrint("errorCode: ", code, "errorMessage: ", message as Any)
}
}
func createConfiguration() -> GRVConfiguration {
let configuration = GRVConfiguration()
return configuration
}
func createExtensionDelegate() -> GRVExtensionDelegate {
let extensionDelegate = GRVExtensionDelegate()
return extensionDelegate
}
func registerWalletServices() {
let oAuthServiceMetaInfo = IAPWalletBaseServiceProvider(
type: IAPWalletServiceType(category: .acl, type: IAPWalletServiceProtocolDefaultTypes.OAUTH),
name: NSStringFromClass(OAuthService.self))
let walletAPIManager = IAPWalletAPIManager()
walletAPIManager.registerServices(metaInfos: [
oAuthServiceMetaInfo
])
IAPWalletContextManager.instance.serviceManager = walletAPIManager
}
}
MemberService
This section explains the workflow and integration process of the MemberService interface, which obtains the members' information for the mini program.
Workflow
The interaction workflow of the MemberService interface differs depending on the following use cases:
- For requests by mini programs
- For requests by IAPMiniProgram SDK
For requests by mini programs
For requests by IAPMiniProgram SDK
Procedures
Follow the procedure to integrate the MemberService interface:
Step 1: Implement MemberService
Create a class that implements the MemberService interface. Within this class, implement the getMemberInfo
method to fetch the member information according to the specified strategy.
For the complete code samples, see Samples (Swift).
Step 2: Register MemeberService to SDK
Before the SDK initialization logic, call the registerServices API to register the MemberService interface to IAPMiniProgram SDK.
Refer to the following sample code for the registration:
import UIKit
import IAPConnect
import GRVAppContainer
import IAPWalletAPI
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
let window: UIWindow = {
let tmp = UIWindow(frame: UIScreen.main.bounds)
tmp.backgroundColor = .white
return tmp
}()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let homeViewController = HomeViewController()
let navigationController = UINavigationController(rootViewController: homeViewController)
window.rootViewController = navigationController
window.makeKeyAndVisible()
registerWalletServices()
setupMiniProgramSDK()
return true
}
func setupMiniProgramSDK() {
let config = IAPConnectInitConfig()
config.riverConfiguration = createConfiguration()
config.riverExtensionDelegate = createExtensionDelegate()
IAPConnectClient.sharedInstance().initWithContext(config) {
debugPrint("init success")
} failure: { code, message in
debugPrint("errorCode: ", code, "errorMessage: ", message as Any)
}
}
func createConfiguration() -> GRVConfiguration {
let configuration = GRVConfiguration()
return configuration
}
func createExtensionDelegate() -> GRVExtensionDelegate {
let extensionDelegate = GRVExtensionDelegate()
return extensionDelegate
}
func registerWalletServices() {
let memberServiceMetaInfo = IAPWalletBaseServiceProvider(
type: IAPWalletServiceType(category: .acl, type: IAPWalletServiceProtocolDefaultTypes.ACCOUNT),
name: NSStringFromClass(MemberInfoService.self))
let walletAPIManager = IAPWalletAPIManager()
walletAPIManager.registerServices(metaInfos: [
memberServiceMetaInfo
])
IAPWalletContextManager.instance.serviceManager = walletAPIManager
}
}
PaymentService
This section explains the workflow and integration process of the PaymentService interface , which initiates the payment process and handle the payment result.
Workflow
Procedures
Follow the procedure to integrate the PaymentService interface:
Step 1: Implement PaymentService
Create a class that implements the PaymentService interface. Within this class, implement the pay
method to initiate the payment process and request for payment with the type of order, and handle the payment result.
For the complete code samples, see Samples (Swift).
Step 2: Register PaymentService to SDK
Before the SDK initialization logic, call the registerServices API to register the PaymentService interface to IAPMiniProgram SDK.
Refer to the following sample code for the registration:
import UIKit
import IAPConnect
import GRVAppContainer
import IAPWalletAPI
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
registerWalletServices()
setupMiniProgramSDK()
return true
}
func setupMiniProgramSDK() {
let config = IAPConnectInitConfig()
config.riverConfiguration = createConfiguration()
config.riverExtensionDelegate = createExtensionDelegate()
IAPConnectClient.sharedInstance().initWithContext(config) {
debugPrint("init success")
} failure: { code, message in
debugPrint("errorCode: ", code, "errorMessage: ", message as Any)
}
}
func createConfiguration() -> GRVConfiguration {
let configuration = GRVConfiguration()
return configuration
}
func createExtensionDelegate() -> GRVExtensionDelegate {
let extensionDelegate = GRVExtensionDelegate()
return extensionDelegate
}
func registerWalletServices() {
IAPWalletServicesRegistrator.registerWalletServices(for: [
IAPWalletServiceProtocolDefaultTypes.PAYMENT
])
}
}
CodeService
This section explains the workflow and integration process of the CodeService interface, which provides QR code or barcode.
Workflow
Procedures
Follow the procedure to integrate the CodeService interface:
Step 1: Implement CodeService
Create a class that implements the CodeService interface. Within this class, implement the scan
method to launch the QR code or barcode scanner and return the code.
For the complete code samples, see Samples (Swift).
Step 2: Register CodeService to SDK
Before the SDK initialization logic, call the registerServices API to register the CodeService interface to IAPMiniProgram SDK.
Refer to the following sample code for the registration:
import UIKit
import IAPConnect
import GRVAppContainer
import IAPWalletAPI
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
registerWalletServices()
setupMiniProgramSDK()
return true
}
func setupMiniProgramSDK() {
let config = IAPConnectInitConfig()
config.riverConfiguration = createConfiguration()
config.riverExtensionDelegate = createExtensionDelegate()
IAPConnectClient.sharedInstance().initWithContext(config) {
debugPrint("init success")
} failure: { code, message in
debugPrint("errorCode: ", code, "errorMessage: ", message as Any)
}
}
func createConfiguration() -> GRVConfiguration {
let configuration = GRVConfiguration()
return configuration
}
func createExtensionDelegate() -> GRVExtensionDelegate {
let extensionDelegate = GRVExtensionDelegate()
return extensionDelegate
}
func registerWalletServices() {
IAPWalletServicesRegistrator.registerWalletServices(for: [
IAPWalletServiceProtocolDefaultTypes.CODE
])
}
}
Class IAPWalletServicesRegistrator
class IAPWalletServicesRegistrator {
static func registerWalletServices(for types: [String]) {
var serviceMap: [String: (category: IAPWalletServiceCategory, clsName: String)] = [
IAPWalletServiceProtocolDefaultTypes.OAUTH: (.acl, NSStringFromClass(OAuthService.self)),
IAPWalletServiceProtocolDefaultTypes.PAYMENT: (.acl, NSStringFromClass(PaymentService.self)),
IAPWalletServiceProtocolDefaultTypes.ACCOUNT: (.acl, NSStringFromClass(MemberInfoService.self)),
IAPWalletServiceProtocolDefaultTypes.CODE: (.foundation, NSStringFromClass(CodeService.self)),
IAPWalletServiceProtocolDefaultTypes.DEEPLINK: (.foundation, NSStringFromClass(DeeplinkService.self))
]
var metaInfos = types.compactMap { (type: String) -> IAPWalletBaseServiceProvider? in
guard let (category, clsName) = serviceMap[type] else { return nil }
return IAPWalletBaseServiceProvider(
type: IAPWalletServiceType(category: category, type: type),
name: clsName
)
}
let walletAPIManager = IAPWalletAPIManager()
walletAPIManager.registerServices(metaInfos: Set(metaInfos))
IAPWalletContextManager.instance.serviceManager = walletAPIManager
}
}