Alipay Payment

Step 1: Alipay. Properties

alipay_url=https://openapi.alipay.com/gateway.do # # app id app_id = 2018020102122556 private key app_private_key=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCdQeknhM2rhiGAH6V0ljxn3rAWIdzduTEQuteTfwjnZtvMhQPuuN1b /88D5yMuaZhZNFeUdWb+SmtP9DAzAWWgnT13T0YhJcxP6txm7JBRrjadCRt+LOFxPiPQk5t9fH7yXjw9i4uMDsNJeTncrVZ/AZYrk0ESC9anJR8XeuBc3HE8 T4fqlKKl35jlumIWrPbPNQhKGXaGcOnpiaXO9qYYUSP/tnrjNYXHOso0yBs4YTl+LLX2TJ12p3n/oX6HnL4zQgtN5k4QasHP7CIig1ngcVQGfWsMm4djI9KX NXvGLQPfMQEmyb71mM5OCdl1MtAc6OaIAymhSv2hOLNIuyodAgMBAAECggEAe05/P5mGm4QlKI2n8u8KlneqovASe1kG/BNFjkYB+VBR8OAr4TfbepPvAyRu Fap+5xN/yMz14VcBJkRWtufVhEdHNxJV7w/wUIncIGhGEYYFFMVbZWhTrbQH6TiUp6TC9dCmc6vD1CKPRkFj+YGBXT0lPy3LzBa0TYNyCbszyhthrgkpuFYb B0R93IPvvBh5NJFXQytwNb2oVopC9AQWviqnZUZcT0eJ087dQ1WLPa6blBD8DP1PUq0Ldr6pgKfObFxIj8+87DlJznRfdEsbqZlS7jagdw5tLr71WJpctIGP qKpgvajfePP/lj3eY82BKQB+aTw0zmAiB05Yes4LgQKBgQDq3EiQR8J1MEN2rpiLt1WvDYYvKVUgOY7Od//fRPgaMBstbe4TzGBpR8E+z267bHAWLaWtHkfX 6muFHn1x68ozEUWk/nZq0smWnuPdcy4E7Itbk36W2FF/rOZB7j5ddlC9byrxDSNgcf9/FA/CU+i5KVQpLYfsk2dvwomvu0aFVQKBgQCraXpxzMmsBx4127Ls ZDO5bxfxb6nqzyK4NPe0VaGiRg8oaCWczcLz1J5iRqC9QeEwsSt4XU1sYBMTcsFpA0apZpm3prH2HJRx/isNENesaHcihF0mMd0WxU3xyRvWSDeZV5A1Zy1Z EJ+p17DGwb2j+yo2uBrDNXBgBWEzXwiRqQKBgBdXFvsHtqKQzlOQHGbeLGy+KlSrheMy9Sc9s7cLkqB/oWPNZfifugEceW71jGqh5y29EZb3yGoDyPWsxwi4 Rxr2H3a7Nyd8lT4bwkdyt+MTYvIR4WW6T7chhqyMsbP2GyYIUzsrdBWUnrCRXNOSJTGpksyY0sZHC+OGcMp/EQ4VAoGBAIISSVL/pm1+/UK7U1ukcced8JpK NLM0uVD1CJ50eHHOHgR4e0owrWYfioxisejLjBlJ6AWvL2g0w2T3qKKKVN2JOM4ulU5/w3l4+KwygqaWowizTogEQJPd5ta52ADTzjTzSD/t6nByd+YHAWLh c4lyt0bMj6pf68VBb8/upm75AoGAGAYz79IVHp9eppykufjNcWu6okkG8tZnzuyaWKW/CuKKBWMaTk0vcyQlfJfxIBccoQrBuYyXBdcpPuZ/ys2C25pNrkAC UhIKNgnMc0floJoYEfJzetw / 3 ciimwu4njzvqoaojaga58oo2 + fub43Xn25Jq4rvSVe3oLdb5xWkw5Q = # public key alipay_public_key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhkZi6W0wn/prX+NIIF9ATb5Z8ReKK4hFYtBrweDfGHD1mNW7YIZY4G5hE7 S2Sry8eFXlFgSlBWlJ4fVnDaK9MkVThpwE2H65ooVlK/wLuyPqovIVpMt/utva5Ayuzv7eQOWK45FdLDNDlK8QLoBko6SS+YbnWnf7a+mrf4NAS4UFClpfe8 Byqe8XIraO2Cg4Ko5Y5schX39rOAH8GlLdgqQRYVQ2dCnkIQ+L+I4Cy9Mvw3rIkTwt3MBU+AqREXY4r5Bn6cmmX/9MAJbFqrofGiUAqG+qbjTcZAzgNPfuiD # 0 ZXGT/YYjMQMzck75BOmwnYOam2ajODUSQn8Xybsa7wQIDAQAB callback address Return_payment_url = http://localhost:8085/member/pay/alipay/callback/return # asynchronous address need outside the network can access (temporarily didn't write) Notify_payment_url = http://60.205.215.91/alipay/callback/notifyCopy the code

Step 2: PayController

package com.macro.mall.portal.controller; import com.alibaba.fastjson.JSON; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.request.AlipayTradePagePayRequest; import com.macro.mall.common.api.CommonResult; import com.macro.mall.model.OmsOrderItem; import com.macro.mall.model.PaymentInfo; import com.macro.mall.portal.config.AlipayConfig; import com.macro.mall.portal.service.OmsPortalOrderService; import com.macro.mall.portal.service.PaymentService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import net.sf.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * payment management */ @controller @API (tags = "PayController", @requestMapping ("/member/pay") public Class PayController {@autoWired Private PaymentService paymentService; @Autowired private OmsPortalOrderService omsPortalOrderService; @Autowired AlipayClient alipayClient; @apioperation (" pay ") @requestMapping (value = "alipay/submit", method = RequestMethod.GET) @ResponseBody public String goToPay( String orderSn, BigDecimal totalAmount) {/ / according to the order number for the order details information OmsOrderItem OmsOrderItem = omsPortalOrderService. GetOrderByOrderSn (orderSn); / / get the commodity name String productName = omsOrderItem. GetProductName (); / / create PC scene order and payment request object AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest (); / / create the corresponding request/API/set synchronization return address, HTTP/HTTPS beginning string alipayRequest setReturnUrl (AlipayConfig. Return_payment_url); // The Alipay server actively notifies the merchant of the specified page HTTP/HTTPS path in the server. alipayRequest.setNotifyUrl(AlipayConfig.notify_payment_url); Map<String,String> requestMap = new HashMap<>(); requestMap.put("out_trade_no",orderSn); Requestmap. put("product_code","FAST_INSTANT_TRADE_PAY"); Requestmap. put("total_amount","0.01"); Requestmap. put("subject",productName); / / name of commodity / / fill business parameters alipayRequest. SetBizContent (JSON. ToJSONString (requestMap)); String form=""; Try {// Call the SDK to generate the form form = alipayClient.pageExecute(alipayRequest).getBody(); } catch (AlipayApiException e) { e.printStackTrace(); } // Generate (save) payment information PaymentInfo PaymentInfo = new PaymentInfo(); paymentInfo.setOutTradeNo(orderSn); PaymentInfo. SetPaymentStatus (" unpaid "); paymentInfo.setOrderId(String.valueOf(omsOrderItem.getOrderId())); paymentInfo.setTotalAmount(totalAmount); paymentInfo.setSubject(productName); paymentInfo.setCreateTime(new Date()); paymentService.save(paymentInfo); / / send the check to pay the result of the message queue, paymentService. SendDelayPaymentCheck (orderSn, 5); return form; ResponseBody @requestMapping (value = "/ Alipay /callback/return",method = ResponseBody @requestMapping (value = "/ Alipay /callback/return",method = Requestmethod.get) public CommonResult callBackReturn(HttpServletRequest Request){// Map<String,String> paramsMap = new HashMap<String, String>(); Map parameterMap = request.getParameterMap(); for(Iterator<String> iter = parameterMap.keySet().iterator(); iter.hasNext();) { String name = iter.next(); String[] values = (String [])parameterMap.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1 ) ? valueStr + values [i] : valueStr + values[i] + ","; } paramsMap.put(name,valueStr); } String outTradeNo = request.getParameter("out_trade_no"); String tradeNo = request.getParameter("trade_no"); String sign = request.getParameter("sign"); try { boolean b = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key,AlipayConfig.charset,AlipayConfig.sign_type); } catch (AlipayApiException e) {e.printStackTrace(); } / / modify payment information, idempotence check / * Boolean b = paymentService checkPaymentStatus (outTradeNo); if(! b){ PaymentInfo paymentInfo = paymentService.checkPaymentResult(outTradeNo); paymentService.updatePayment(request.getQueryString(),outTradeNo,tradeNo); / / message sending system, concurrent goods payment message queue paymentService. SendPaymentSuccess (outTradeNo, paymentInfo getPaymentStatus (), tradeNo); }*/ return commonresult. success(" pay successfully "); }}Copy the code

Step 3: Send a message queue to check the payment result

@Autowired private OmsOrderSettingMapper orderSettingMapper; @Autowired private AmqpTemplate amqpTemplate; * @param orderSn * @param count */ @override public void sendDelayPaymentCheck(String orderSn, Int count) {/ / get order timeout OmsOrderSetting orderSetting = orderSettingMapper. SelectByPrimaryKey (1 l); long delayTimes = orderSetting.getNormalOrderOvertime() * 60 * 1000; HashMap<Object, Object> hashMap = new HashMap<>(); hashMap.put("out_trade_no",orderSn); hashMap.put("count",count); / / to queue delay sending messages amqpTemplate. ConvertAndSend (QueueEnum. QUEUE_PAY_CANCEL. GetExchange (), QueueEnum.QUEUE_PAY_CANCEL.getRouteKey(), hashMap, new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { / / set to the message delay millisecond value message. GetMessageProperties () setExpiration (String) the valueOf (delayTimes)); return message; }}); }Copy the code

Step 4: Process the message queue that sends to check the payment result

package com.macro.mall.portal.component; import com.macro.mall.model.PaymentInfo; import com.macro.mall.portal.service.PaymentService; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.HashMap; /** * @component @rabbitListener (queues = "mall.pay.cancel") public class PayReceiver {@autoWired PaymentService paymentService; @RabbitHandler public void handle(HashMap mapMessage){ try { String outTradeNo = mapMessage.get("out_trade_no").toString(); int count = Integer.parseInt(mapMessage.get("count").toString()); If (count > 0) {system.out.println (" doing "+ (6-count) +" pay result check "); / / call alipayClient interface, according to the payment information PaymentInfo out_trade_no query PaymentInfo = paymentService. CheckPaymentResult (outTradeNo); Thread thread = new Thread(); thread.start(); Thread.sleep(10000); / / determine whether already pay success if (paymentInfo. GetPaymentStatus ()! =null&&(paymentInfo.getPaymentStatus().equals("TRADE_SUCCESS") || PaymentInfo. GetPaymentStatus (.) the equals (" TRADE_FINISHED "))) {/ / trading success or failure, record the transaction status System. Out. The println (" check successful trading results, record transaction status..." ); / / / / modify payment information modify the state of the payment information Boolean b = paymentService. CheckPaymentStatus (outTradeNo); if(! B) {/ / modify as paid paymentService. UpdatePayment (paymentInfo. GetCallbackContent (), outTradeNo, paymentInfo. GetAlipayTradeNo ()); // Send system messages, Initiates the concurrent commodity payment business message queue paymentService.sendPaymentSuccess(paymentInfo.getOutTradeNo(),paymentInfo.getPaymentStatus(),paymentInfo.getAlipayTradeN o()); Println (" + (6-count) + ");}} else {// not paid // delay check system.out.println (" + (6-count) + "); paymentService.sendDelayPaymentCheck(outTradeNo, count - 1); }} else {system.out. println(" payout ", "payout", "payout", "payout") ); } } catch (Exception e) { } } }Copy the code

Step 5: Invoke the alipayClient interface and query the payment information according to out_trade_no

@Autowired AlipayClient alipayClient; @override public PaymentInfo checkPaymentResult(String outTradeNo) { PaymentInfo paymentInfo = new PaymentInfo(); AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); Map<String,Object> mapString = new HashMap<String,Object>(); mapString.put("out_trade_no",outTradeNo); String s = JSON.toJSONString(mapString); request.setBizContent(s); AlipayTradeQueryResponse response = null; try { response = alipayClient.execute(request); } catch (AlipayApiException e) { e.printStackTrace(); } / / wait payment, payment, payment failure, success is over paymentInfo. SetCallbackTime (new Date ()); paymentInfo.setOutTradeNo(outTradeNo); paymentInfo.setCallbackContent(response.getMsg()); If (response.isSuccess()){system.out.println (" transaction created "); paymentInfo.setPaymentStatus(response.getTradeStatus()); paymentInfo.setAlipayTradeNo(response.getTradeNo()); } else {system.out.println (" transaction not created "); } return paymentInfo; }Copy the code

Step 6: Send the system message and start the concurrent commodity payment business message queue

@Autowired private OmsOrderSettingMapper orderSettingMapper; @Autowired private AmqpTemplate amqpTemplate; /** * Send system message, * @param outTradeNo * @param paymentStatus * @param tradeNo */ @override public void sendPaymentSuccess(String outTradeNo, String paymentStatus, String tradeNo) { HashMap<String, String> hashMap = new HashMap<>(); hashMap.put("outTradeNo",outTradeNo); hashMap.put("paymentStatus",paymentStatus); hashMap.put("tradeNo",tradeNo); OmsOrderSetting orderSetting = orderSettingMapper.selectByPrimaryKey(1L); long delayTimes = orderSetting.getNormalOrderOvertime() * 60 * 1000; / / to queue delay sending messages amqpTemplate. ConvertAndSend (QueueEnum. QUEUE_PAYMENT_SUCCESS_CANCEL. GetExchange (), QueueEnum.QUEUE_PAYMENT_SUCCESS_CANCEL.getRouteKey(), hashMap, new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { / / set to the message delay millisecond value message. GetMessageProperties () setExpiration (String) the valueOf (delayTimes)); return message; }}); }Copy the code

Step 7: Process the sending system message and start the concurrent commodity payment business message queue

package com.macro.mall.portal.component; import com.macro.mall.portal.service.OmsOrderService; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.HashMap; Queues = "mall.paysuccess.cancel") public class PaySuccessReceiver {/** * queues = "mall.paysuccess.cancel") @Autowired private OmsOrderService orderService; @RabbitHandler public void handle(HashMap mapMessage){ String outTradeNo = mapMessage.get("outTradeNo").toString(); String trackingNo = mapMessage.get("tradeNo").toString(); String paymentStatus = mapMessage.get("paymentStatus").toString(); / / consumer code orderService. UpdateOrder (outTradeNo paymentStatus, trackingNo); / / send a order message queue, to the success of consumption by the inventory system inventory interface (or call) the orderService. SendOrderResult (outTradeNo); }}Copy the code

Step 8: Send an order success message queue to be consumed by the inventory system (or call the inventory interface)

@Autowired private OmsOrderItemMapper omsOrderItemMapper; @Autowired private AmqpTemplate amqpTemplate; /** * Send an order success message queue, Public void sendOrderResult(String outTradeNo) {OmsOrderItemExample omsOrderItemExample = new OmsOrderItemExample(); OmsOrderItemExample.Criteria criteria = omsOrderItemExample.createCriteria(); criteria.andOrderSnEqualTo(outTradeNo); List<OmsOrderItem> omsOrderItems = omsOrderItemMapper.selectByExample(omsOrderItemExample); OmsOrderItem omsOrder = omsOrderItems.get(0); Long productId = omsOrder.getProductId(); HashMap<String, Long> objectObjectHashMap = new HashMap<>(); objectObjectHashMap.put("productId",productId); / / to queue delay sending messages amqpTemplate. ConvertAndSend (QueueEnum. QUEUE_STOCK_QUEUE. GetExchange (), QueueEnum.QUEUE_STOCK_QUEUE.getRouteKey(),objectObjectHashMap, new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { / / set to the message delay millisecond value message. GetMessageProperties () setExpiration (String) the valueOf (0)); return message; }}); }Copy the code

Step 9: Process the message queue that sends a successful order, which is consumed by the inventory system (or calls the inventory interface)

package com.macro.mall.portal.component; import com.macro.mall.portal.service.PmsSkuStockService; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.HashMap; @Component @RabbitListener(queues = "mall.stock.cancel") public class StockReserve { @Autowired private PmsSkuStockService pmsSkuStockService; @RabbitHandler public void handle(HashMap<String, Long > productId) {/ / according to the order quantity of the order number query the Integer productQuantity = pmsSkuStockService. GetProductQuantity (productId); / / on the product id sellers reduction inventory stock list pmsSkuStockService. UpdateOrderStock (productQuantity, productId. Get (" productId ")); }}Copy the code

If you are not familiar with RabbitMQ, check out blog.csdn.net/java_wxid/a…