The payment effect can be seen at the end of the article.
Students who have paid for it know that Alipay and WeChat payments are only suitable for small payments. If they encounter large business scenarios, they still have to pay for them.
Like other payment platforms, UnionPay also provides corresponding payment channels according to different mobile terminals, such as online gateway payment, cloud flash payment APP payment (original mobile payment control), enterprise online banking payment (merchant version), mobile web page payment (WAP payment), QR code payment, etc.
The first step to connect to the platform interface is naturally to have an account. I won't say much about the process of registering an account. Put it on the official website and register yourself.
(https://open.unionpay.com/)
Select the products to be connected, fill in the information and submit the network access application, and there will be business connection.
It is very friendly that the platform will provide test parameters for debugging the interface. In the personal Center - merchant network access test center - test parameters, including test merchant number, test certificate and test address.
With these things, you can start writing code and debugging interfaces. Of course, the most comforting thing is that the platform also provides SDK for your reference. After measurement, it is really only for reference, because you can't run, ha ha 😀.
Although the code is very simple, it still takes effort to integrate successfully.
acp_ The sdk.properties configuration file mainly places some certificate files, which are downloaded from the merchant network access test center.
########################## Transaction sending address of network access test environment ############################# # Message version number, fixed 5.1.0 acpsdk.version=5.1.0 # Signature method, certificate method fixed 01 acpsdk.signMethod=01 ##Test transaction request address acpsdk.frontTransUrl=https://gateway.test.95516.com/gateway/api/frontTransReq.do acpsdk.backTransUrl=https://gateway.test.95516.com/gateway/api/backTransReq.do acpsdk.singleQueryUrl=https://gateway.test.95516.com/gateway/api/queryTrans.do # Whether to verify the CN of the signing certificate, set false for the test environment and true for the production environment. acpsdk.ifValidateCNName=false # Whether to verify the https certificate, set false for the test environment and true for the production environment. acpsdk.ifValidateRemoteCert=false ######################### Network access test environment signature certificate configuration ################################ # Signature certificate path acpsdk.signCert.path=/data/acp_test_sign.pfx # Signature certificate password, test environment fixed 000000 acpsdk.signCert.pwd=000000 # The signature certificate type is fixed and does not need to be modified acpsdk.signCert.type=PKCS12 ########################## Encryption certificate configuration ################################ # Sensitive information encryption certificate path acpsdk.encryptCert.path=/data/acp_test_enc.cer ########################## Signature verification certificate configuration ################################ # Intermediate certificate verification path acpsdk.middleCert.path=/data/acp_test_middle.cer # Verify root certificate path acpsdk.rootCert.path=/data/acp_test_root.cer
ACP_ Put the sdk.properties configuration file in the root directory
Write another configuration class, UnionPayConfig, and load the certificate content when starting
@Component @Configuration @EnableConfigurationProperties({UnionProperties.class}) public class UnionPayConfig { private UnionProperties union; public UnionPayConfig(UnionProperties union) { this.union = union; SDKConfig.getConfig().loadPropertiesFromSrc(); } }
The PC side calls up the payment page. Pay attention to the transaction amount. The unit is minute, and there can be no decimal point. The result is to open the payment page in the form of form.
@GetMapping(value="webPay") public void webPay(HttpServletResponse resp) throws IOException { logger.info("UnionPay computer payment"); UnionPayParam param = new UnionPayParam(); param.setOrderId(UnionConfig.getCurrentTime()) .setTxnTime(UnionConfig.getCurrentTime()) .setTxnAmt("330000") .setReqReserved(param.getOrderId()); unionPayService.webPay000202(param, resp); Map<String, String> data = new HashMap<>(29); // Version number, Omni channel default data.put("version", UnionConfig.version); // For character set encoding, UTF-8 and GBK can be used data.put("encoding", UnionConfig.encoding_UTF8); // Signature method data.put("signMethod", SDKConfig.getConfig().getSignMethod()); // Transaction type, 01: consumption data.put("txnType", "01"); // Transaction subtype, 01: self service consumption data.put("txnSubType", "01"); // Business type 000202: B2B data.put("bizType", "000202"); // Channel type fixed 07 data.put("channelType", "07"); // Merchant number data.put("merId", unionProperties.getMerId()); // Access type, 0: direct merchant data.put("accessType", "0"); // Merchant order number, 8-40 digits, alphanumeric, can not contain "-" or "", and can customize the rules data.put("orderId", param.getOrderId()); // The order sending time takes the system time in the format of YYYYMMDDhhmmss. The current time must be taken, otherwise txnTime will be reported as invalid data.put("txnTime", param.getTxnTime()); // Transaction currency (generally 156 yuan for domestic merchants) data.put("currencyCode", "156"); // Transaction amount, unit: Fen, without decimal point data.put("txnAmt", CommonUtils.subZeroAndDot(param.getTxnAmt())); // For business scenarios, refer to the interface specification for values data.put("bizScene", "110001"); // Payee account name data.put("payeeAcctNm", URLEncoder.encode(unionProperties.getPayeeAcctNm(),UnionConfig.encoding_UTF8)); // Payee account number data.put("payeeAcctNo", unionProperties.getPayeeAcctNo()); // Name of receiving bank data.put("payeeBankName", URLEncoder.encode(unionProperties.getPayeeBankName(),UnionConfig.encoding_UTF8)); // Front desk notification address data.put("frontUrl", unionProperties.getFrontUrl()); // Background notification address data.put("backUrl", unionProperties.getBackUrl()); // Order timeout data.put("payTimeout", new SimpleDateFormat("yyyyMMddHHmmss").format(System.currentTimeMillis() + 15 * 60 * 1000)); // When the requestor reserves the field and the content will not appear "& = {} []", you can fill in the data directly data.put("reqReserved", Base64.encodeBase64String(param.getReqReserved().getBytes(UnionConfig.encoding_UTF8))); Map<String, String> reqData = AcpUtils.sign(data,UnionConfig.encoding_UTF8); String requestFrontUrl = SDKConfig.getConfig().getFrontRequestUrl(); String html = AcpUtils.createAutoFormHtml(requestFrontUrl,reqData,UnionConfig.encoding_UTF8); logger.info("Print request HTML,This is a request message:{}", html); resp.getWriter().write(html);
Like other payment methods, the payment result is notified to the developer by asynchronous notification, where the business logic is processed, such as changing the order status to paid.
@PostMapping(value="unionPayNotify") public void unionPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { logger.info("Start of UnionPay receiving background notification"); String encoding = request.getParameter(SDKConstants.param_encoding); // Get the background notification parameters sent by UnionPay notification server Map<String, String> reqParam = AcpUtils.getAllRequestParam(request); Map<String, String> valideData = new HashMap<>(); if (!reqParam.isEmpty()) { Iterator<Map.Entry<String, String>> it = reqParam.entrySet().iterator(); valideData = new HashMap<>(reqParam.size()); while (it.hasNext()) { Map.Entry<String, String> e = it.next(); String key = e.getKey(); String value = e.getValue(); value = new String(value.getBytes(encoding), encoding); valideData.put(key, value); } } if (!AcpUtils.validate(valideData, encoding)) { logger.info("UnionPay verification signature result[fail]."); } else { logger.info("UnionPay callback result parameters=====: {}", JSON.toJSONString(valideData)); logger.info("UnionPay verification signature result[success]."); AsyncNotifyResult result = JSON.parseObject(JSON.toJSONString(valideData), AsyncNotifyResult.class); // Response code String respCode = result.getRespCode(); // Response information String respMsg = result.getRespMsg(); if (StringUtils.equals("00", respCode) && StringUtils.equals("success[0000000]", respMsg)) { // Merchant order number String orderId = result.getOrderId(); // UnionPay inquiry serial number String queryId = result.getQueryId(); // UnionPay order sending time String txnTime = result.getTxnTime(); String txnAmt = result.getTxnAmt(); // Auxiliary information String reqReserved = result.getReqReserved(); logger.info("reqReserved=====: {}", new String(Base64.decodeBase64(reqReserved), UnionConfig.encoding_UTF8)); // TODO // UnionPay does not return the payment time, which is generated by the system itself logger.info("Process business logic, orderId: {},to update queryId: {},txnTime: {}=====", orderId, queryId, txnTime); } response.getWriter().print("ok"); } }
Look at the effect
This is the test environment. Select the card number, enter the verification code, and click Submit
If code is required
UnionPay payment to realize code docking
The scenery meets, the future can be expected, thank you for reading, we'll see you again
The golden cudgel in my hand can reach the sky and explore the sea
Previous: Alipay small program template development, a complete set of processes