Alipay+Alipay+

Alipay+ MPP Server SDK for Non-Client-SDK Integration

This topic introduces the business flows that involve Alipay+ MPP Server SDK for Non-Client-SDK Integration and provides a step-by-step guide on how to integrate the server SDK.

1. How it works

This section introduces the business flows among different parties. The involved parties include the merchant, MPP client,
MPP server, Alipay+ server SDK, and Alipay+.

1.1 Overall business flow

The following figure illustrates the overall business flow among the merchant, MPP, Alipay+ server SDK, and Alipay+.

image.png

Figure 1-1. Overall business flow

The overall business flow consists of the following steps:

1. Scan a QR code

1.1 The merchant presents a QR code to the customer.

1.2 The customer uses the MPP client to scan the QR code.

2. Identify the QR code

2.1 The MPP client sends a request to the MPP server to identify the QR code.

2.2 If the code value cannot be recognized, the MPP server calls the Alipay+ server SDK to identify the code.

2.3 The Alipay+ server SDK returns the identification result to the MPP server. If the code can be processed by Alipay+, the Alipay+ server SDK also includes the code type and further action in the result.

  1. Decode the code value
    • If the code is an order code, the MPP server sends a request to Alipay+ to decode the code value.
    • If the code is an entry code, the MPP client redirects the user to place an order. After the order is placed, the MPP server obtains the order code that is generated based on the order information and then sends a request to Alipay+ to decode the code value.
  1. Process the payment

4.1 Alipay+ calls the MPP server to process the payment.

4.2 The MPP server returns the cashier page URL to the MPP client. The user is then redirected to the cashier page to confirm the payment.

1.2 Alipay+ Server SDK business flow

The following figure illustrates the business flow between the MPP and Alipay+ server SDK.

image.png

Figure 1-2. Alipay+ server SDK business flow

The Alipay+ server SDK business flow consists of the following steps:

1. Initialize the Alipay+ server SDK

1.1 The MPP server initializes the Alipay+ server SDK by calling the ac.code.service.CodeIdentificationService#init API.

1.2 The Alipay+ server SDK loads route configurations from the route configuration HTTP server.

1.3 If route configurations are successfully loaded from the server, the Alipay+ server SDK saves downloaded route configurations to storage; otherwise, the Alipay+ server SDK might read route configurations from storage based on the value set in the ac.route.init-route-config-level property.

1.4 The Alipay+ server SDK schedules updates.

2. Identify the QR code by calling the identifyCode API

2.1 The MPP client calls the MPP server to identify the code.

2.2 If the code value cannot be recognized, the MPP server sends a request to the Alipay+ server SDK to identify the code by calling the ac.code.service.CodeIdentificationService#identifyCode API.

2.3 The Alipay+ server SDK returns the identification result to the MPP server. If the code can be processed by Alipay+, the Alipay+ server SDK also includes the code type and further action in the result.

2. Integration guide

The integration guide shows you how to integrate the Alipay+ server SDK with your server.

2.1 Requirements

The Alipay+ server SDK has the following requirements:

  • JDK 6 or higher.
  • Maven 3.3.9 or higher if you integrate the SDK via Maven.

2.2 Integration

Read the following sections for details about how to integrate the Alipay+ server SDK.

2.2.1 Initializing POM

To initialize POM dependencies, complete the following steps:

  1. Contact your solution architect to obtain the Alipay+ MPP Server SDK for Non-Client-SDK Integration JAR file. If you use a private Maven repository manager like Nexus, upload the downloaded JAR file to your repository. Refer to the following sample for details on how to upload the file. Replace placeholders as required.
copy
mvn deploy:deploy-file \
  -DgroupId=com.alipayconnect.mobile \
  -DartifactId=mpp-server-sdk \
  -Dversion=<mpp-server-sdk-version> \
  -Dpackaging=jar \
  -Dfile=<path-to-jar-file> \
  -DrepositoryId=<id-to-map-on-server-section-of-settings.xml> \
  -Durl=<url-of-the-repository-to-deploy>
  1. Download POM dependencies from Maven. Refer to the following sample for details on how to download POM dependencies from Maven. The minimum required versions of open source dependencies are listed in the sample.
copy
<!--Component dependencies-->
<dependency>
    <groupId>com.alipayconnect.mobile</groupId>
    <artifactId>mpp-server-sdk</artifactId>
    <version>${mpp.server.sdk.version}</version>
</dependency>
<dependency>
    <groupId>com.alipayconnect.mobile</groupId>
    <artifactId>mpp-server-sdk-framework</artifactId>
    <version>${mpp.server.sdk.framework.version}</version>
</dependency>

<!--Open source dependencies-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <!--Minimum version: 4.3.4.RELEASE-->
    <version>5.3.20</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <!--Minimum version: 1.7.0-->
    <version>1.7.9</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <!--Minimum version: 1.2.51.sec09-->
    <version>1.2.83</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <!--Minimum version: 3.7-->
    <version>3.8.1</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <!--Minimum version: 4.4.1-->
    <version>4.5.8</version>
    <exclusions>
        <exclusion>
            <artifactId>commons-logging</artifactId>
            <groupId>commons-logging</groupId>
        </exclusion>
    </exclusions>
</dependency>

<!--Logging library dependencies. See next section-->

Note:

Logging library dependencies are not included in the sample. For more information about logging library dependencies, see 2.2.2 Initializing logging library.

2.2.2 Initializing logging library

Based on SLF4J, MPP developers can use a custom logging library. Refer to the following samples for details on how to initialize the Log4j2 logging library, which is an option provided by Alipay+. The MPP can also choose other logging libraries.

To initialize the Log4j2 logging library, complete the following steps:

  1. Add Log4j2 dependencies to your project.
copy
<!--Log4j2 dependencies-->
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.1</version>
</dependency>

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.4.2</version>
</dependency>
  1. Add your custom Log4j2 configuration file to the classpath. The following configuration is a sample that prints logs to the console. The actual logging configuration depends on your project. See Configuration for details.
copy
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample Log4j2 configuration which just print logs to the console.-->
<Configuration>
    <Appenders>
        <Console name="STDOUT-APPENDER" target="SYSTEM_OUT">
            <PatternLayout pattern="%-5p %c{2} - %m%n%throwable" charset="UTF-8"/>
        </Console>

        <Console name="STDERR-APPENDER" target="SYSTEM_ERR">
            <PatternLayout pattern="%-5p %c{2} - %m%n%throwable" charset="UTF-8"/>
        </Console>

    </Appenders>

    <Loggers>
        <AsyncLogger name="STDOUT" additivity="false" level="info">
            <AppenderRef ref="STDOUT-APPENDER"/>
        </AsyncLogger>

        <AsyncLogger name="STDERR" additivity="false" level="info">
            <AppenderRef ref="STDERR-APPENDER"/>
        </AsyncLogger>

        <AsyncRoot level="info">
            <AppenderRef ref="STDOUT-APPENDER"/>
        </AsyncRoot>
    </Loggers>
</Configuration>

2.2.3 Importing bean definitions from components

To import bean definitions from the Alipay+ server SDK, use the following configuration files:

File Name

Description

component-server-sdk.xml

Component beans.

Sample code:

copy
<import resource="classpath:/META-INF/config/component-server-sdk.xml"/>

2.2.4 Defining component properties

To define component properties, complete the following steps:

  1. Register your properties file by using XML or Java.

Sample code for XML:

copy
<context:property-placeholder location="classpath:ac-sdk.properties" />

Sample code for Java:

copy
@PropertySource("classpath:ac-sdk.properties")
@Configuration
public class AcSdkConfig {

    @Bean
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}
  1. Add component properties.
copy
ac.route.pull-route-config-url=<route-config-http-server-url>
ac.route.init-route-config-level=STORAGE
ac.route.pull-route-config-fixed-delay=30
ac.route.pull-route-config-exception-retry-delay=2
ac.route.save-route-config-path=/home/admin/ac-sdk/
ac.route.http.socket-timeout=3000
ac.route.http.connect-timeout=3000
ac.route.http.connection-request-timeout=3000
ac.route.mode = <type-of-environment>
ac.route.client-id=<client-ID-assigned-by-Alipay+>

The following table shows all component properties in detail:

Property

Type

Description

Required

Suggested value

ac.route.pull-route-config-url

String

HTTP server URL where route configurations are downloaded

M

Provided by Alipay+. The recommended default value is https://open-sea.alipayplus.com/aps/api/v1/codes/inquiryCodeRules. ​

ac.route.init-route-config-level

String

The minimum required level of the loaded route configurations when initializing the Alipay+ server SDK. The initialization fails if the minimum-level configurations fail to be loaded. Valid values are:

  • REMOTE: remote server
  • STORAGE: local storage

M

Decided by the MPP.

REMOTE is useful if loaded route configurations are always the latest. STORAGE is useful if custom storage implementation is used and the loaded configurations are at least from storage. It is recommended that you put the configuration file into storage before initialization.

ac.route.pull-route-config-fixed-delay

int

Interval of pulling route configurations in minutes

M

30

ac.route.pull-route-config-exception-retry-delay

int

Retry interval of pulling route configurations in minutes

M

2

ac.route.save-route-config-path

String

Path where pulled route configurations are saved

M

Decided by the MPP. Example: /home/admin/ac-sdk/

Note:

If custom RouteConfigStorageSpi implementation is provided or the value of ac.route.init-route-config-level is REMOTE, this property can be empty.

ac.route.http.socket-timeout

int

Socket timeout for HTTP client in milliseconds

M

3000

ac.route.http.connect-timeout

int

Connection timeout for HTTP client in milliseconds

M

3000

ac.route.http.connection-request-timeout

int

Connection request timeout for HTTP client in milliseconds

M

3000

ac.route.mode

String

The type of environment where the SDK is called.

M

Valid values are:

  • PROD: indicates the production environment.
  • SHADOW: indicates the acceptance testing environment.

Note: Set the value to SHADOW during acceptance testing.

ac.route.client-id

String

The client ID of the MPP that is assigned by Alipay+.

M

Note: The value of this parameter must be prefixed with "TEST_" during acceptance testing.

2.2.5 Implementing SPI (optional)

Implement RouteDataSpi to customize the route configuration storage according to your requirements. If you do not implement this SPI, the Alipay+ server SDK saves route configuration data to the local file specified on the ac.route.save-route-config-path property by default. If you implement this SPI, pay attention to the capacity limit of your storage because route configuration data contain all matching rules and can be as large as dozens of KBs. For more information, see Alipay+ MPP Server SDK for Non-Client-SDK Integration interfaces.

To import bean definitions from the Alipay+ server SDK without the default SPI, use the following configuration files:

File name

Description

component-server-sdk-base.xml

Component beans without defaultSpiImpl

Note:

To avoid importing bean definitions repeatedly, do not import component-server-sdk.xml.

If you implement RouteDataSpi, you must register your SPI implementation bean in the spring context into which you import the Alipay+ server SDK bean definitions.

Sample code:

copy
<import resource="classpath:META-INF/config/component-server-sdk-base.xml"/>
<bean id="routeDataSpi" class="ac.code.RouteDataSpiImpl"/>

2.2.6 Initializing components

Use the following API to initialize components before identifying codes. For more information, see Alipay+ MPP Server SDK for Non-Client-SDK Integration interfaces.

API

Description

ac.code.service.CodeIdentificationService#init

Initialize the code identification service.

2.2.7 Identifying codes

When the MPP cannot recognize the code value, use the following API to check whether the code can be processed by Alipay+. For more information, see Alipay+ MPP Server SDK for Non-Client-SDK Integration interfaces.

API

Description

ac.code.service.CodeIdentificationService#identifyCode

Identify codes that can be processed by Alipay+.

2.3 Known issue

When the MPP server cannot connect to Alipay+'s route configuration server because of limited access to the public network, try the following methods:

  • Set up a proxy service at first.
  • Extend DefaultRouteDataSpi to only overwrite RouteDataSpi.readRouteConfigFromRemote, or implement RouteDataSpi to overwrite all methods including RouteDataSpi.readRouteConfigFromRemote.
  • Overwrite the RouteDataSpi.readRouteConfigFromRemote method. The Alipay+ server SDK will send a URI to SPI when the route configuration update is required.

Note:

The method of setting up a proxy server is not recommended. Route configurations being managed by Alipay+ is easier and safer.

3. Troubleshooting

You can check logs provided by the Alipay+ server SDK to obtain helpful information for troubleshooting. The log format depends on your logging framework configuration. The following sample shows the log printed by the Alipay+ server SDK. In this sample, you can use the log keyword [AC_SDK][STORAGE_CONFIG_SAVE_FAILED] for troubleshooting.

copy
2019-11-20:2019-11-20 23:58:05,635 INFO  repository.impl.RouteConfigRepositoryImpl mobile-mock-wallet-saas-plugin_1.0.0.20191019 - [AC_SDK][STORAGE_CONFIG_SAVE_FAILED]

The following table shows the log keywords and suggested solutions:

Log keyword

Condition

Solution

[AC_SDK][STORAGE_CONFIG_SAVE_FAILED]

Some error occurs when saving route configuration data to storage.

Check the log, which usually contains exception stack or error messages.

[AC_SDK][STORAGE_CONFIG_READ_FAILED]

Some error occurs when reading route configuration data from storage.

Check the log, which usually contains exception stack or error messages.

[AC_SDK][REMOTE_CONFIG_DOWNLOAD_FAILED]

Fail to pull route configurations.

  1. Check the log, which usually contains exception stack or error messages.
  2. Check whether your server can access the route configuration HTTP server.

[AC_SDK][ROUTE_CONFIG_IS_INVALID]

The loaded route configuration is invalid or blank.

  1. Check the log to identify where the invalid route configuration is loaded.
  2. If the route configuration is loaded from a remote server, contact Alipay+ to fix the issue. If the route configuration is loaded from storage, the reason might be that no configuration exists in the storage or the stored configuration is invalid. Check the log for details.

[AC_SDK][SCHEDULER_THREAD_INTERRUPTED]

The thread which schedules updates is interrupted.

Check whether the thread scheduler can be interrupted in your integration code and you might restart your server to initialize the Alipay+ server SDK again.

[AC_SDK][UNKNOWN_CODE]

Some error occurs when recognizing the Alipay+ code.

  1. Check the log, which usually contains exception stack or error messages.
  2. Contact Alipay+ to ask for technical support.

4. Monitoring

The following log keywords are recommended to be monitored:

  • [AC_SDK][STORAGE_CONFIG_SAVE_FAILED]
  • [AC_SDK][STORAGE_CONFIG_READ_FAILED]
  • [AC_SDK][REMOTE_CONFIG_DOWNLOAD_FAILED]
  • [AC_SDK][ROUTE_CONFIG_IS_INVALID]
  • [AC_SDK][SCHEDULER_THREAD_INTERRUPTED]
  • [AC_SDK][UNKNOWN_CODE]

The Alipay+ server SDK also logs unsuccessful API calling for monitoring:

copy
[AC_SDK][INVOKE_PROCESS_ERROR][resultCode: %s, message: %s]

5. FAQs

Where does the Alipay+ server SDK save the route configurations locally?

If you implement RouteConfigStorageSpi, the location to save the route configurations depends on your implementation; otherwise, the route configurations are saved in the local file system. The path for saving configurations is configured through the ac.route.save-route-config-path property.

What is the size of the route configuration data to be stored?

The configuration data size changes. The configuration data contain all matching rules and the size can be as large as dozens of KBs. Pay attention to the capacity limit of your storage when you implement RouteConfigStorageSpi.

How often are the route configurations updated?

The route configurations are updated for one time when initializing the Alipay+ server SDK and are scheduled to be updated periodically. To set the interval of the route configurations update, configure the ac.route.pull-route-config-fixed-delay and ac.route.pull-route-config-exception-retry-delay properties.

How often are route configurations in storage read?

The route configurations in storage might be read when initializing the Alipay+ server SDK conditionally. When identifying the code, the route configurations are not read.

How does the MPP process the code if the code is not an Alipay+ code?

It's recommended to open the code by appending AlipayConnect in the User-Agent header.