# sdkProxy

`POST /aps/api/v1/mobile/sdkProxy`

The Mobile Payment Provider (MPP) server uses the **sdkProxy** API to proxy the request from the Alipay+ NFC SDK to the Alipay+ server.

In the Alipay+ NFC scenario, the request proxy steps are listed below:

1.  When making a request, the Alipay+ NFC SDK first sends a request body to the MPP app.
2.  The MPP app constructs an HTTPS request body using the request body that the SDK provides and then sends the HTTPS request body to the MPP server.
3.  The MPP server obtains the customer ID and then constructs an HTTPS request by adding the request header and customer ID into the HTTPS request body provided by the MPP app. Then the MPP server sends the HTTPS request to the Alipay+ server.

When using this API, the MPP server needs to obtain only the customer ID and add it to the request body. Then, the MPP server sends the request to the Alipay+ server through this API.

> **Note**: The expiry time of the **sdkProxy** API is 10 seconds. The MPP server needs to set the connection expiry time between Alipay+ and the MPP server to longer than 10 seconds.

## Structure

A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see:

-   [Request header](https://docs.alipayplus.com/alipayplus/alipayplus/api_mpp/api_overview.md#3mLq0)
-   [Response header](https://docs.alipayplus.com/alipayplus/alipayplus/api_mpp/api_overview.md#YdmVS) 

> **Note**:
>
> 1.  Set the data type of each parameter (except array) as String. This means that you must use double quotation marks (" ") to enclose the parameter value. Examples:
>
> -   If the data type of a parameter is Integer and its value is 20, set it as "20".
> -   If the data type of a parameter is Boolean and its value is `true`, set it as "true".
>
> 2.  For optional parameters that are not required in your case, you can take one of the following actions:
>
> -   Exclude the parameters from the request body.
> -   Set the parameter values as `null` (without the double quotation marks).
>
> Do NOT leave the optional parameters empty by setting their values as `""`; otherwise, an error might occur.

## Request parameters

#### sdkRequestHeader (String, REQUIRED)

The SDK request header.

This parameter is encapsulated within the SDK and sent by the MPP client. The MPP server constructs HTTPS request with the content of this parameter. The MPP server should not modify the content.

#### sdkRequestData (String, REQUIRED)

The SDK request data body.

This parameter is encapsulated within the SDK and sent by the MPP client. The MPP server constructs HTTPS request with the content of this parameter. The MPP server should not modify the content.

#### customerId (String, REQUIRED)

The unique ID that is assigned by the MPP to identify a customer.

## Response parameters

#### result (Result, REQUIRED)

The result of the business processing, including the result status, result code, and result message. For more information about how to return the result, see _How to return the result_.

##### resultCode (String, REQUIRED)

The result code that indicates the detailed processing result.

More information:

- Maximum length: 64 characters

##### resultStatus (String, REQUIRED)

The result status that indicates the processing result. Valid values are:

-   `S`: Successful
-   `F`: Failed
-   `U`: Unknown

##### resultMessage (String)

The result message that describes the result code in detail.

More information:

- Maximum length: 256 characters

#### sdkResponseHeader (String, CONDITIONAL)

The SDK response header.
The parameter is mandatory when _result.resultCode_ is `SUCCESS`.

#### sdkResponseData (String, CONDITIONAL)

The SDK response data body.

The parameter is mandatory when _result.resultCode_ is `SUCCESS`.

## Sample

The following sample code shows how the MPP server constructs and sends a HTTPS request by adding customer ID into the MPP client's request body.

> **Note**: This sample code only provides a general implementation on how to add customerId into the request body, some unrelated steps are skipped.

```java
public class NFCProxyHandler {

    /**
     * send request to Alipay+ server when receive the Client App proxy request.
     *
     * @param  body is the generated by Alipay+ NFC SDK
     * @return the response is the Alipay+ Server sdkProxy responseBody
     */
    public String sendRequest(String body) {

        JSONObject jsonObject = JSON.parseObject(body);

        // This step needs to be rewritten according to the actual situation of the MPP; this is just an example.
        String userId = MobileRpcHolder.getLiteSession().get(SessionKey.USER_ID);

        jsonObject.put("customerId", userId);

        String requestBody = JSON.toJSONString(jsonObject);

        // This section skips the steps for MPP to assemble the request header and signing. It is important to note that the body of the request should use the requestBody described above.
        String signValue = genSignValue(httpMethod, path, clientId, reqTime, requestBody);

        // Skip some steps...

        HttpResult rsp = sendHttpRequest(requestUrl, httpMethod, header, requestBody);

        if (rsp == null) {
            throw new RuntimeException("HttpResult is null.");

        } else {
            int httpRespCode = rsp.getRspCode();
            String rspBody = rsp.getRspBody();
            if (httpRespCode != 200) {
                throw new RuntimeException("Response data error, rspBody:" + rspBody);
            }

            signatureVerification(httpMethod, path, clientId, rspTime, rspBody, rspSignValue);

            return rspBody;
        }
    }
}
```

Alipay+ server processes the request and returns the response to the MPP server.

> **Note**: The reponse data must be returned to the SDK entirely. If the MPP app returns null data or no data is returned, the SDK will determine that the request has failed.

## Result/Error codes

| Code | Value | Message |
| --- | --- | --- |
| SUCCESS | S | Success |
| ACCESS_DENIED | F | Access is denied. |
| INVALID_API | F | The called API is invalid or not active. |
| INVALID_CLIENT | F | The client is invalid. |
| INVALID_SIGNATURE | F | The signature is invalid. |
| KEY_NOT_FOUND | F | The key is not found. |
| MEDIA_TYPE_NOT_ACCEPTABLE | F | The server does not implement the media type that is acceptable to the client. |
| METHOD_NOT_SUPPORTED | F | The server does not implement the requested HTTPS method. |
| PARAM_ILLEGAL | F | Illegal parameters. For example, non-numeric input, invalid date. |
| PROCESS_FAIL | F | A general business failure occurred. Do not retry. |
| REQUEST_TRAFFIC_EXCEED_LIMIT | U | The request traffic exceeds the limit. |
| UNKNOWN_EXCEPTION | U | An API call failed, which is caused by unknown reasons. |

## Request

```json
{
  "sdkRequestHeader": "{\"AppId\":\"WALLET_ID\",\"AppKey\":\"WALLET_ID_ANDROID\",\"workspaceId\":\"default\",\"Content-Type\":\"application/x-www-form-urlencoded\"}",
  "sdkRequestData": "operationType=ap.mobileprod.mcop.wrapper.action&requestData=%5B%7B%22context%22%3A%5B%7B%22bizType%22%3A%22MOBILEAPPLY%22%2C%22campaignId%22%3A%2228100213CAMPAIGN202104161910233172448%22%2C%22requestId%22%3A%2229f40f14-0faa-451e-8545-68e716df282a%22%7D%5D%2C%22envInfo%22%3A%7B%22appId%22%3A%22%22%2C%22appVersion%22%3A%221.33.0-test02-debug%22%2C%22extendInfo%22%3A%7B%7D%2C%22latitude%22%3A%22%22%2C%22locale%22%3A%22en-US%22%2C%22longitude%22%3A%22%22%2C%22miniProgramVersion%22%3A%223.1.0%22%2C%22osType%22%3A%22Android%22%2C%22osVersion%22%3A27%2C%22sdkVersion%22%3A%22%22%2C%22terminalType%22%3A%22miniapp%22%2C%22tokenId%22%3A%22%22%7D%7D%5D&ts=1620471100",
  "customerId": "20200415111215830128DANAW3ID123000000002"
}
```

## Response

```json
{
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "Success",
    "resultStatus": "S"
  },
  "sdkResponseData": "{\"traceId\":\"21d5e7a4177082559889265231219\",\"success\":true,\"errorActions\":{},\"extendInfo\":{},\"status\":\"SILENT\"}",
  "sdkResponseHeader": "{\"Server-Time\":\"1770825598\",\"Mgw-TraceId\":\"21d5e7a4177082559889265231219\",\"Ac-UserId\":\"210220900023739770336\",\"Result-Status\":\"1000\"}"
}
```