package com.ruoyi.web.line; import java.io.IOException; import java.io.Serializable; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.UUID; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.HmacAlgorithms; import org.apache.commons.codec.digest.HmacUtils; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.StringEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.web.pcApi.domain.TOrderManage; import com.ruoyi.web.pcApi.domain.TOrderManageTotal; import com.ruoyi.web.pcApi.service.ITOrderManageService; @Component public class LinePay implements Serializable { private static final long serialVersionUID = 1L; /** log */ private static final Logger log = LoggerFactory.getLogger(LinePay.class); @Autowired private LineConfig lineConfig; @Autowired private ITOrderManageService orderManageService; /** * create the line pay request body. * * @param orderManageTotal 订单管理-总对象 * @return line pay request body */ public SendBody createSendBody(TOrderManageTotal orderManageTotal, String deptName) { //create line pay request body SendBody sendBody = new SendBody(); //订单金额 sendBody.setAmount(orderManageTotal.getOrderMoney().intValue()); //order id sendBody.setOrderId(String.valueOf(orderManageTotal.getId())); for (TOrderManage orderManage : orderManageTotal.getOrderList()) { TOrderManage order = orderManageService.selectTOrderManageById(orderManage.getId()); //send order Orders ord = new Orders(); //注文番号 ord.setId(order.getOrderNo()); //決済金額 ord.setAmount(order.getOrderMoney().intValue()); //パッケージの名前(または、加盟店内の出店業者の名前) ord.setName(deptName); //add the packages sendBody.add(ord); OrderDetail detail = new OrderDetail(); //販売商品の名前 detail.setName(order.getCommodityName()); //販売商品の画像URL detail.setImageUrl(order.getFaceImg()); //商品数 detail.setQuantity(1); //各商品の決済金額 detail.setPrice(order.getOrderMoney().intValue()); ord.add(detail); } //call back urls RedirectUrls callBack = new RedirectUrls(); //confirm url callBack.setConfirmUrl(lineConfig.callbankConfirmUrl); //cancel url callBack.setCancelUrl(lineConfig.callbankCancelUrl); sendBody.setRedirectUrls(callBack); return sendBody; } /** * set the header info * @param request * @throws URISyntaxException */ private void setHeaderAndEntity(HttpPost request, String sendBody) throws URISyntaxException { String nonce = UUID.randomUUID().toString(); request.setHeader("Content-Type", "application/json"); request.setHeader("X-LINE-ChannelId", lineConfig.channelId); request.setHeader("X-LINE-Authorization-Nonce", nonce); StringBuffer message = new StringBuffer(); //channelSecret message.append(lineConfig.channelSecret); //path message.append(request.getUri().getPath()); //body message.append(sendBody); //nonce message.append(nonce); byte[] bytes = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_256, lineConfig.channelSecret.getBytes()).doFinal(message.toString().getBytes()); byte[] byteArray = Base64.encodeBase64(bytes); request.setHeader("X-LINE-Authorization", new String(byteArray)); request.setEntity(new StringEntity(sendBody, ContentType.APPLICATION_JSON)); } /** * line pay * @param orderManageTotal */ public LinePayAPOD pay(TOrderManageTotal orderManageTotal, String deptName) { //create request body SendBody sendBody = createSendBody(orderManageTotal, deptName); ObjectMapper mapper = new ObjectMapper(); LinePayAPOD response = null; try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost request = new HttpPost(lineConfig.payUrl); setHeaderAndEntity(request, mapper.writeValueAsString(sendBody)); response = client.execute(request, httpResponse -> mapper.readValue(EntityUtils.toString(httpResponse.getEntity()), LinePayAPOD.class)); log.info(mapper.writeValueAsString(response)); } catch (IOException | URISyntaxException e) { log.error("line pay Request API エラーが発生しました。", e); } return response; } /** * confirm line pay * @param transactionId * @param total */ public LinePayConfirmAPOD payConfirm(String transactionId, long total) { // ConfirmBody body = new ConfirmBody(); body.setAmount(total); ObjectMapper mapper = new ObjectMapper(); MessageFormat form = new MessageFormat(lineConfig.confirmUrl); String formatStr = form.format(new Object[] {transactionId}); LinePayConfirmAPOD response = null; try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost request = new HttpPost(formatStr); setHeaderAndEntity(request, mapper.writeValueAsString(body)); response = client.execute(request, httpResponse -> mapper.readValue(EntityUtils.toString(httpResponse.getEntity()), LinePayConfirmAPOD.class)); log.info(mapper.writeValueAsString(response)); } catch (IOException | URISyntaxException e) { log.error("line pay Confirm API エラーが発生しました。", e); } return response; } /** * 決済完了(売上確定済み)された取引を返金します。 * @param transactionId * @param refundAmount */ public LinePayRefundAPOD payRefund(String transactionId, Long refundAmount) { // RefundBody body = new RefundBody(); body.setRefundAmount(refundAmount); ObjectMapper mapper = new ObjectMapper(); MessageFormat form = new MessageFormat(lineConfig.confirmUrl); String formatStr = form.format(new Object[] {transactionId}); LinePayRefundAPOD response = null; try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost request = new HttpPost(formatStr); setHeaderAndEntity(request, mapper.writeValueAsString(body)); response = client.execute(request, httpResponse -> mapper.readValue(EntityUtils.toString(httpResponse.getEntity()), LinePayRefundAPOD.class)); log.info(mapper.writeValueAsString(response)); } catch (IOException | URISyntaxException e) { log.error("line pay Refund API エラーが発生しました。", e); } return response; } }