.. _9 Payment system: 9 Payment system ============================ Pico payment is a game currency payment system based on the Pico account system, and the settlement method is based on the current game currency unit under Pico (P currency). If the project requires internal purchasing function, please read the contents of this chapter carefully. If the project does not require internal purchasing function, please ignore this chapter. 9.1 Preparations ---------------------------------- 9.1.1 Get the string used for payment ------------------------------------------------------------ - **APP ID** : Unique identifier generated by the developer platform for the application - **APP KEY** : Key generated by the developer platform for the application - **APP Secret** : Key generated by the developer's platform for the application to be used for payment - **Publisher ID** : Developer's ID, also called Merchant ID 9.1.2 Apply to become a Pico developer ----------------------------------------------------------------------- If you wish to publish your app to the Pico Store, you will need to create a developer account and log in to the `Pico Developer Platform`_. .. _Pico Developer Platform: https://developer.pico-interactive.com/ 1. Click the `Become a Developer`_ button on the `Pico Developer Platform`_. .. _Become a Developer: https://devcenter.pico-interactive.com/#/organization .. _Pico Developer Platform: https://developer.pico-interactive.com/ 2. In the **Account** pop-up window, select the region where your account is located: **China mainland / Other regions** and click the **Sign up** button. .. image:: _static/9.1.2.1.png 3. Verify your account - a. If you choose **Other regions**, you need to fill in your email address and set your password, and select the country/region where your account is located, and verify your email account by verification email. - b. If you choose **China mainland**, you need to fill in your cell phone number and set your password, and verify your cell phone number by SMS. .. image:: _static/9.1.2.2.png .. image:: _static/9.1.2.2.png 4. Check the box to accept Pico `PRIVACY POLICY`_ and click the **Register** button. .. _PRIVACY POLICY: https://www.pico-interactive.com/us/terms/privacy.html 5. Check your Email for the **verification** sent to you to complete your registration. 6. **Congratulations!** You are now officially a Pico developer. **Note:** Pico developer account registration is completely **FREE**. 9.1.3 Get application parameters -------------------------------------------------------- 1. **Get Publisher ID** After applying as a developer, enter the developer management platform, click on "My Apps", enter "Apps" and click on the "API" menu to see the developer ID, which will be used as a unique mark for merchants in the payment system. 2. **Create application, select payment type** Developers can enter the application creation phase from the management center. After clicking Create Application, then enter the corresponding platform to perfect the relevant information of application: .. image:: _static/9.1.3.1.png Figure 9.1 Information about application improvement **Note:** Please fill out the application type carefully, and it can’t be modified once you fill it out! - a. Select the application. Pay directly using the P-Coin amount. - b. Select the game. Use product code to pay. Product code is the unique identification of developer's backend for paid props in the game. For in-app purchase of game applications, developers should add commodity codes for unified management in the developer backend. The product code payment configuration interface is as follows: .. image:: _static/9.1.3.2.png Figure 9.2 In-app purchase configuration **Product code definition rules:** - The first digit is a letter, only letters and numbers are allowed, and it should be no more than 20 characters - The product code between different props cannot be repeated - The prop types are divided into consumable prop and non-consumable prop. Consumable prop are reusable commodities, such as gold currency, blood bottle, etc. Non-consumable props are disposable purchased products, such as weapons and unlocking levels. 3. **Get APP ID, APP KEY, APP Secret parameters** After successfully creating an application, the developer platform will assign APP ID, APP KEY, APP Secret parameters for the current application. .. image:: _static/9.1.3.3.png Figure 9.3 APP ID、APP KEY、APP Secret **Now, you have obtained Publisher ID, APP ID, APP KEY and APP Secret.** 9.1.4 Configure application parameters in AndroidManifest.xml --------------------------------------------------------------------------------------------- Enter Edit -> Project Settings..., Expand option OnlinePico Settings under Plugins, check "Enable Payment Module", select actual Region accordingly. To release in Mainland China, select "China", to release in other regions select "NonChina". Select "Both" to release globally. .. image:: _static/9.1.4.1.png Figure 9.4 Select publishing region Populate Merchant ID (Developer ID), APPID, APP KEY, APP secret to following secitons: .. image:: _static/9.1.4.2.png Figure 9.5 Fill in attibutes 9.2 Use of payment system --------------------------------------------- .. image:: _static/9.2.1.jpg Figure 9.6 Workflow of payment system - Firstly, make sure Login API (Pico Login SDK, Pico Paymen Login) returns the success result, then call other payment APIs including pay (Pico Payment Pay with Coin、Pico Payment Pay with Pay Coin), query (Pico Payment Query), get user info (Pico Payment Get User Info、Pico SDKGet User Info) etc. - If logout is needed after logging in, call logout APIs (Pico Logout SDK、Pico Payment Logout). - All above APIs mentioned need to bind corresponding callback events to acquire result. Details can be found in chapter 9.3 9.3 Other related interfaces ---------------------------------------------- 9.3.1 Register ----------------------------------------- Pico provides developers with Oauth2.0-based authentication and authorization, therefore, the users need to log in before paying, and here the Pico Payment Login node or Pico Login SDK node we provide should be used: Pico Login SDK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Execute login action and bind callback event to acquire login result. **Blueprint:** .. image:: _static/9.3.1.1.png **Input:** - Delegate: - Log in Delegate:Bind Login callback event as follow: .. image:: _static/9.3.1.2.png - Callback event params: - Bool: - IsSucceed: - true:Success - false:Failure - FString: - Reason: Use FString to print failure reason. Details can be found in Table 9-1 Reason Code **Output:** None **Return:** None Pico Payment Login ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Execute login action and bind callback event to acquire login result. **Blueprint:** .. image:: _static/9.3.1.3.png **Input:** - Delegate: - Log in Delegate:Bind Login callback event as follow: .. image:: _static/9.3.1.4.png - Callback event params: - Bool: - IsSucceed: - true:Success - false:Failure - FString: - Reason: Use FString to print failure reason. Details can be found in Table 9-1 Reason Code **Output:** None **Return:** None 9.3.2 Logout ----------------------------------------- Log out action can be executed with PicoLogoutSDK or PicoPaymentLogout: Pico Logout SDK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Execute login action and bind callback event to acquire login result. **Blueprint:** .. image:: _static/9.3.2.1.png **Input:** - Delegate: - Log out Delegate:Bind logout callback event as follow: .. image:: _static/9.3.2.2.png - Callback event params: - Bool: - IsSucceed: - true:Success - false:Failure - FString: - Reason: Use FString to print failure reason. Details can be found in Table 9-1 Reason Code **Output:** None **Return:** None Pico Payment Logout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Execute login action and bind callback event to acquire login result. **Blueprint:** .. image:: _static/9.3.2.3.png **Input:** - Delegate: - Log out Delegate:Bind logout callback event as follow: .. image:: _static/9.3.2.4.png - Callback event params: - Bool: - IsSucceed: - true:Success - false:Failure - FString: - Reason: Use FString to print failure reason. Details can be found in Table 9-1 Reason Code **Output:** None **Return:** None ======================================= ========================================= =========================================== **Error Message** **Description** **Reason** ======================================= ========================================= =========================================== TIME_ERROR Timestamp Error Local timestamp and server timestamp have 8 minute or more gap SYSTEM_USER_NOT_FIND_ERROR User not found User not exist for specified tokent SYSTEM_USER_TOEKN_NOT_FIND_ERROE User token not found User token not found SYSTEM_USER_TOKEN_CHECK_FAILURE_ERROR User token verify failed User token not valid SYSTEM_USER_TOKEN_UNKNOWN_ERROR User token verify failed User token verify failure APP_CHECK_ERROR Application verify failed Parameters like APP ID are incorrect ======================================= ========================================= =========================================== Table 9-1 Reason Code 9.3.3 Payment ----------------------------------------- Pico Payment Pay with Coin ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Pay in P coins **Blueprint:** .. image:: _static/9.3.3.1.png **Input:** .. image:: _static/9.3.3.2.png - FString: - OrderNumber: The characters of the order number defined by the merchant. The size is limited within 32 characters, which may contain letters and numbers. - OrderTitle: Order title - ProductDetail: Product detail - Notify Url: The URL to be notified must be a directly accessible URL and cannot be provided with parameters. It is not required. - Int: - PicoCoinCount:Paid P coin - Delegate: - Pay Order with Coin Delegate:Bind callback event as follow .. image:: _static/9.3.3.3.png - Callback event params: - FString: - Code:Check table 9.2 for details - Message:Check table 9.2 for details **Output:** None **Return:** None Pico Payment Pay with Code ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Pay in Pay code **Blueprint:** .. image:: _static/9.3.3.4.png **Input:** .. image:: _static/9.3.3.5.png - FString: - OrderNumber: The characters of the order number defined by the merchant. The size is limited within 32 characters, which may contain letters and numbers. - OrderTitle: Order title - ProductDetail: Product detail - Notify Url: The URL to be notified must be a directly accessible URL and cannot be provided with parameters. It is not required. - PicoPayCode: The product code, which the user can acquire through the 9.1.1 in-game payment configuration. - Delegate: - Pay Order with Coin Delegate:Bind callback event as follow: .. image:: _static/9.3.3.6.png - Callback event params: - FString: - Code:Check table 9.2 for details - Message:Check table 9.2 for details **Output:** None **Return:** None Code and Msg are as follows: ============================ ============================================== Code Message ============================ ============================================== 00000 Network error 10000 Log-in is successful 10001 User does not log in 10002 Please enter the correct amount 10003 Log-in has been expired, please re-log in 11000 Merchant verification is successful 11001 Merchant verification failure 11002 User authentication parameter is wrong or request has been expired 11003 Merchant is not verified 12000 Payment is successful 12001 Payment failure 12003 P currency is insufficient 12004 Balance is available 13000 The order is generated 13001 Get acquisition failure 13002 The order generation failure 14000 The order query is successful 14001 There is no order / the order is wrong 14002 The user cancels payment operation 15000 The product information is not entered 15001 The prepaid ID is not entered 15002 Please enter the Pico payment order number or merchant order number NOAUTH The merchant does not have the interface permission SYSTEMERROR The system is wrong APP_ID_NOT_EXIST There is no APP_ID MCHID_NOT_EXIST There is no MCHID APP_ID_MCHID_NOT_MATCH App_id and mch_id are mismatched LACK_PARAMS The parameters are lacked SIGNERROR The signature is wrong NO_DATA No data is found / the user does not recharge ORDER_EXIST There has been an order PAY_CODE_NOT_EXIST There is no consumption code PAY_CODE_EXIST The user has consumed the product code ============================ ============================================== Table 9-2 Code and Message map 9.3.4 Order query ----------------------------------------- Pico Payment Query Order ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Query payment order from server **Blueprint:** .. image:: _static/9.3.4.1.png **Input:** - FString: - Order Number:Order number in String - Delegate: - Query Order Delegate:Bind callback event as follow: .. image:: _static/9.3.4.2.png - Callback event params: - FString: - Code:Check table 9.2 for details - Message:Check table 9.2 for details **Output:** None **Return:** None 9.3.5 Get user information ----------------------------------------- Pico Payment Get User Info ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Blueprint:** .. image:: _static/9.3.5.1.png **Input:** - Delegate: - User Info Delegate:Bind callback event as follow: .. image:: _static/9.3.5.2.png - FString: - Info:an unprocessed json string(string)check result in table 9.3 **Output:** None **Return:** None Pico SDKGet User Info ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Blueprint:** .. image:: _static/9.3.5.3.png **Input:** - Delegate: - User Info Delegate:Bind callback event as follow: .. image:: _static/9.3.5.4.png - FString: - Info:an unprocessed json string(string)check result in table 9.3 **Output:** None **Return:** None - **Info:** An unprocessed Json string. Here is an example of a successful query: .. code-block:: java {"ret_code":"0000", "data" : { "aboutme":"", "birthday" : 1460476800000, "phone" : "13100000000", "username" : "Admin", "email" : "", "gender" : "male", "lastname" : "", "openid" : "4f3148bdc34d9bca104927729a173b64", "firstname" : "", "avatar" : "http://172.31.83.11/upload/6dd6ee103714e967846c3d38ae48d511", "signature" : "14a25d7219d8dfc91e55f63286ae5c0a", "country" : "China", "city" : "" }, "ret_msg":"Successful call" } The query failure example is as follows: .. code-block:: java { "ret_code":"00003000", "ret_msg" : "Signature verification failure" } **List of other ret_code codes and ret_msg:** ====================== ============================================== ret_code ret_msg ====================== ============================================== 0000 Successful request 00020000 Database operation failure 9999 System error 00001000 Parameter error 00002000 Data parsing failure 00003000 Signature verification failure 00003001 Time verification failure 00060000 User not found 00060001 User password error 00060002 Unknown user login error 00061000 User token finding failure 00061001 User token verification failure 00061002 Unknown user token error 00070001 Application verification failure 00071001 Application key verification failure 00080001 OAUTH_CODE verification failure 00090001 REFRESH_TOKEN verification failure 00100001 ACCESS_TOKEN verification failure 00110001 SCOPE verification failure ====================== ============================================== Table 9.3 On Pico Get User Info Callback output parameter ret_code code and ret_msg list 9.4 Developer server interaction ------------------------------------------------------------------ After the payment is completed, the payment system will send the relevant payment results and user information to the merchant, and the merchant needs to receive and process them and return a response. When the background notifies the interaction, if the receiving of the merchant’s response by the payment system receives is not successful or overtime, the notification should be considered as failed, and the payment system will periodically re-initiate the notification through certain policies to maximize the success rate of the notification, but it may not guarantee that the notification will be eventually successful. The same notification may be sent to the merchant system repeatedly and the merchant system must be able to process duplicate notifications correctly. The recommended practice is to firstly check the status of the corresponding service data when it receives and processes the notification, and determine whether the notification has been processed, it should be re-processed if it has not been processed, and the result return will be successful directly if it has been processed. Before the status check and processing of business data, data locks should be used for concurrency control to avoid data confusion caused by function reentry. The merchant server needs to implement the following interface for receiving the request from the Pico server and get the payment result and user information of the Pico payment system: ========================= ======================================================================== Name Payment result callback interface Request type POST Request URL Pay, parameter notify_url transmitted by PayOrder Request format JSON Return format JSON Is login required Yes Request parameter For details, see "Table 9.3 notification parameters in payment result notification" Return parameter: +------------------+---------------+--------------------+ | Name of parameter| Type and range| Description | +------------------+---------------+--------------------+ | ret_code | string | Wrong code | +------------------+---------------+--------------------+ | ret_msg | string |Wrong message string| +------------------+---------------+--------------------+ For details see "Table 9.4 Return results" Return parameter example { "ret_code":"SUCCESS", "ret_msg":"OK" } Update instruction ========================= ======================================================================== Table 9.4 Interfaces that the merchant server needs to implement ============================ ============= ======== ====== ============ Field name Variable name Required Type Description ============================ ============= ======== ====== ============ Return status code ret_code Yes String SUCCESS/FAIL This field is the communication identifier, rather than transaction identifier. The success of the transaction should be determined based on the check on result code Return information ret_msg No String Return error information if not empty, the cause could be Signature failure and parameter format check error. Error code sub_code No String Error code Error code description sub_msg No String Wrong returned information error Pico payment order number trade_no Yes String Pico payment order number Merchant order number out_trade_no Yes String The order number within the merchant system Application ID app_id Yes String Application APP_ID approved by the platform Merchant ID mch_id Yes String Assigned merchant number for payment User identifier open_id Yes String Unique identifier of the user under the merchant appid Device number device_id No String Terminal device number Random string nonce_str Yes String Random string: no longer than 32 bits.Recommended random number generation algorithm. (https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3) Signature signature Yes String For signature, see the signature generation algorithm (https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3) Business result result_code Yes String SUCCESS/FAIL Transaction type trade_type Yes String Payment type Currency type fee_type Yes String Currency type Total amount total_fee Yes String Total order amount Paid-in amount receipt_fee Yes String Paid-in amount The amount paid by the buyer buyer_pay_fee No String The amount paid by the buyer Voucher or discount coupon_fee No String Voucher or discount Merchant data package attach No String Merchant data package, returned as it is Payment completion time pay_time Yes String Payment completion time, in the format: yyyy-MM-dd HH: mm:ss ============================ ============= ======== ====== ============ Table 9.5 Notification parameters in payment results notification ====================== =============== ========== ======== ================================================================================ Field name Variable name Required Type Description ====================== =============== ========== ======== ================================================================================ Status code returned ret_code Yes String SUCCESS/FAIL. SUCCESS indicates that the merchant has received and verified the notification successfully. Return information ret_msg No String Return error information if not empty, the cause could be Signature failure and parameter format check error. ====================== =============== ========== ======== ================================================================================ Table 9.6 Return results **Special remarks:** The signature verification must be performed for the contents of the payment result notification in the merchant system to prevent "false notification" due to data leakage and capital loss. The signature verification rule is as follows: 1. Remove the signature parameter from the returned list of parameters, and simultaneously add key = "app_secret", value=paykey, then sort it naturally according to the key value, separate the multiple parameters with &, and finally take MD5 encryption. 2. Compare the encrypted string with the get signature The signature function is as follows: .. code-block:: java /** * result :Map collection of gotten data * paykey :i.e. the paykey on the developer platform. */ public static String createSign(Map result, String paykey) { if (result == null || result.size() == 0) return null; result.put("app_secret", paykey); String sign = result.get("signature"); result.remove("signature"); String[] tmp = new String[result.size()]; int i = 0; for (String key : result.keySet()) { tmp[i++] = key; } Arrays.sort(tmp); String signTemp = ""; for (String string : tmp) { if (result.get(string) == null) continue; signTemp += string + "=" + URLEncoder.encode(result.get(string).toString() , "utf-8") + "&"; } if (signTemp.endsWith("&")) signTemp = signTemp.substring(0, signTemp.length() - 1); Log.i(TAG, "createSign: " + signTemp); String localSign = MD5.MD5(sign); return localSign.equal(sign); }