Development is introduced
Because some later needs need to use alipay website payment business, and recently I learned the development of NodeJS backend, so I found some materials from the Internet, and alipay open platform has no ready-made Demo cases, only NodeJS SDK, so, I spent some time trying to develop a sample Demo using NodeJS for later development projects. Test DEMO: github.com/xiluotop/No…
Development steps
- The text process from the creation of an order to the successful payment:
Front-end page -> send order information to the server -> server confirmation information, Send confirmation information to the client -> client confirmation information send order request to the server -> server verifies order request information -> Server sends order generation like Alipay -> Alipay returns order data to the server -> Server sends form information of Alipay to the client -> Client jumps to the Payment page of Alipay -> Client payment success -> Alipay allows the client to jump to the page specified by the server -> Alipay asynchronously notifies the server of the payment result of the order -> The server receives the asynchronous notification for corresponding business processing.
- The general process for Alipay to invoke the payment interface:
The preparatory work
- Install the SDK tool of Alipay:www.npmjs.com/package/ali…
npm install alipay-sdk
- Obtain relevant information of Alipay application
- appid
- The secret key
- Application of the private key
- Application of public key
- Alipay public key (it can be obtained from the secret key query on alipay Open platform)
- The gateway
- The steps of access are available at https://jiangck.com/articles/2019/08/10/1565412139037.html
- The following table of contents should be prepared:
The development work
- Configure the SDK
- Create alipay_config.js this js script is used to set information about the SDK
const fs = require('fs'); const path = require('path'); // Configure basic information here const AlipayBaseConfig = { appId: ' './ / application ID privateKey: fs.readFileSync(path.join(__dirname, './sandbox-pem/private_pem2048.txt'), 'ascii'), // Apply the private key alipayPublicKey: ' '.// Alipay public key gateway: 'https://openapi.alipaydev.com/gateway.do'.// The application gateway of Alipay is the gateway of sandbox environment charset:'utf-8'.// Character set encoding version:'1.0'.// Version, default 1.0 signType:'RSA2' // The decoded version of the secret key }; module.exports = { AlipayBaseConfig: AlipayBaseConfig, // Expose the configuration module for initial call } Copy the code
- Create createOrder.js file to encapsulate the module that generates alipay orders
- Import SDK environment:
const AlipaySDK = require("alipay-sdk").default;
- Import configuration:
const alipayConfig = require(path.join(__dirname, './alipay_config.js')); // The previously defined alipay_config.js configuration module
- Get the alipaySDK instantiation object and initialize it:
const alipay = new AlipaySDK(alipayConfig.AlipayBaseConfig)
- Encapsulation createOrder
- According to the official example: www.yuque.com/chenqiu/ali… , Alipay. Trade.page. Pay (unified ordering and payment page interface) returns an HTML fragment at last, so formData is needed for data encapsulation request
- Introduces the alipayFormData constructor to create the form required by the site to pay for
const AlipayFormData = require('alipay-sdk/lib/form').default;
- The createOrder package and the detailed code are as follows:
// Write a function that creates a payment order and asynchronously waits for execution async function createOrder(goods) { let method = 'alipay.trade.page.pay'; // Unified receiving order and payment page interface // Public parameters can be passed based on service requirements // let params = { // app_id: '2016101000654289', // Application ID // method: method, // call the interface // format: 'JSON', // returns data // charset: 'utF-8 ', // character encoding Sign_type: 'RSA2', // Check type // timestamp: getFormatDate() // version: '1.0', // version // } // A set of parameters according to the API documentation provided by the official let bizContent = { out_trade_no: Date.now(), // Generate an order number based on the timestamp, product_code: 'FAST_INSTANT_TRADE_PAY'.// Product code is currently only supported total_amount: goods.cost, // Commodity prices subject: goods.goodsName, // Product name timeout_express: '5m'.// The timeout period passback_params: JSON.stringify(goods.pack_params), // A parameter that will be returned, which can be used to customize the product information for final notification } const formData = new AlipayFormData(); // Get an instantiated object formData.addField('returnUrl'.'http://jiangck.com:9999/payresult'); // The client will jump back to the address after successful payment formData.addField('notifyUrl'.'http://jiangck.com:9999/notify.html'); // Alipay will asynchronously notify the callback address after the payment is successful, which can only be received on the public IP address formData.addField('bizContent', bizContent); // Add the required set of parameters to the form // Asynchronously send an order generation request to Alipay. The second parameter is a public parameter. If it is not needed, pass in an empty object const result = await alipay.exec(method, {}, { formData: formData }); // Return the result information of the order return result; } Copy the code
- Expose the method for generating orders
module.exports = { createOrder: createOrder } Copy the code
- Import SDK environment:
- Create checksign.js check module
- Attestation is in when to pay for success, pay treasure to asynchronous setting good callback address to the server to send a post request, to tell us the payment information of server users and server end is based on the asynchronous notification logic to handle business, rather than rely on alipay synchronous jump, and after paying treasure to send the asynchronous notification request, The server needs to do a verification check, this step is necessary, because money transactions must be rigorous, must verify the authenticity of the requested information. Logical processing can only be done after it is legal. The packaged verification function is also a tool based on alipaySDK, which is only used for convenient invocation. The code is as follows:
const path = require('path'); // For notification verification ------ Configure the Alipay SDK environment / / import the SDK const AlipaySDK = require("alipay-sdk").default; // Import the configuration const alipayConfig = require(path.join(__dirname, './alipay_config.js')); / / initialization const alipaySdk = new AlipaySDK(alipayConfig.AlipayBaseConfig); async function checkNotify(obj) { const result = await alipaySdk.checkNotifySign(obj); return result; } module.exports = checkNotify; Copy the code
- Create the mysql.js module, which is used to encapsulate the storage work of the database
- The code is as follows:
/* This custom module is used to add and query mysql database orders */ // Import the mysql module const mysql = require('mysql'); / / configure the mysql const mysqlConfig = { host: 'localhost'.// Database host name port: '3306'./ / the port number user: 'root'./ / user name password: '123456'./ / password database: 'alipay'.// Database name } // encapsulate the query function function selectSql(sqlstr,callback) { // Establish a database connection let sql = mysql.createConnection(mysqlConfig); let result = null; if (sql) { sql.query(sqlstr, callback); // Close the database connectionsql.end(); }}// Encapsulate add function function addSql(sqlstr,callback) { return selectSql(sqlstr,callback); } // Expose two database operation methods module.exports = { selectSql: selectSql, addSql: addSql } Copy the code
- Create server.js to create an HTTP server, and do the request processing code for each interface as follows:
const path = require("path"); const bp = require('body-parser'); // Introduce custom mysql tools const mysql = require(path.join(__dirname, './mysql.js')); / / into the express const express = require('express'); // Get the Express instance object let app = express(); // Set up managed static resources app.use(express.static(path.join(__dirname, './public'))); // Process the POST request parameters app.use(bp.urlencoded({ extended: false })); // The front end responds to the data object to create the order app.get('/payinfo', (req, res) => { let data = req.query; // Make a simple commodity judgment if (data && (data.goodsName === 'Daviosaur' || data.goodsName === 'Broad ice' || data.goodsName === 'spirits' || data.goodsName === 'QQB') && data.count && data.cost) { res.send(Object.assign(data, { code: 200,})); }else { res.setHeader('content-type'.'application/javascript'); res.send('Wrong message, please try again!!' ) '); }})// Get the custom module to create the order const createOrder = require(path.join(__dirname, './createOrder.js')).createOrder; // Get the validation custom module const checkSign = require(path.join(__dirname, './checkSign.js')); // Generate an order request app.post('/createOrder', (req, res) => { console.log(req.body.price); req.body.pack_params = { payName: req.body.payName, goodsName: req.body.goodsName, price: req.body.price, count: req.body.count, cost: req.body.cost, } async function asyncCreate() { const result = await createOrder(req.body); res.send(result); } asyncCreate(); }); // Display the payment information app.get('/payresult', (req, res) => { let htmlStr = ' '; htmlStr += `<p>` + 'Merchant Order No.' + ':' + req.query.out_trade_no + '</p>' htmlStr += `<p>` + 'Alipay Transaction Order Number' + ':' + req.query.trade_no + '</p>' htmlStr += `<p>` + 'Transaction Amount' + ':' + req.query.total_amount + 'RMB < / p >' htmlStr += `<p>` + 'Trading time' + ':' + req.query.timestamp + 'RMB < / p >' htmlStr += '
Payment successful!!
' res.send(htmlStr); }) app.post('/notify.html', (req, res) => { // Output the verification result async function checkResult(postData) { let result = await checkSign(postData); if (result) { // console.log(' Order paid successfully!! Please do something ') // console.log(req.body); let data = req.body; let goods = JSON.parse(data.passback_params); let sqlStr = ` insert into order_list value("${data.out_trade_no}","${data.trade_no}","${goods.goodsName}", ${goods.price}.${goods.count}.${data.total_amount}", "Payment successful ","${goods.payName}"); `; // If alipay succeeds in processing, alipay will always send asynchronous notifications periodically res.end('success'); mysql.addSql(sqlStr) } } checkResult(req.body); }) // Query order interface app.get('/getorder', (req, res) => { mysql.selectSql('select * from order_list', (err, result) => { result = Object.assign({ code: 200.msg: 'Obtain success'.list: JSON.stringify(result), }) res.send(result); }); }) app.listen(9999, () = > {console.log('server start with 9999... '); }) Copy the code - Public Static resource
- Static resources are only used by the front end to show the operation of the client. Specific files can be accessed from github open source Demo, which contains a dump file of The Alipay. SQL database, or can be created by itself.
conclusion
- The above steps is a alipay site payment interface call Demo simple development.
- The problems encountered during the development process are as follows:
- Public key configuration in SDK configuration, it is clear to fill in alipay public key, not application public key
- The secret key algorithm has to correspond to RSA and RSA2 and you have to figure out, what’s the encryption
- Check the failure to check the encryption algorithm, alipay public key, use private key/public key encryption type
- After passing the verification, you must want to pay the string “success” of the response success information, otherwise it will always be notified asynchronously, resulting in multiple business processing.
- This test DEMO has been open source Github, you can click me to get the test DEMO. If you are helpful, please Star under O(∩_∩)O.
- This is also my first payment test demo, there will be bugs, I will add more interface test demo and step by step improvement, if there is any problem can leave a message to communicate with oh.