| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- package com.ruoyi.app.utils.zaloPay;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.ruoyi.app.utils.zaloPayCrypto.HMACUtil;
- import org.apache.http.NameValuePair;
- import org.apache.http.client.entity.UrlEncodedFormEntity;
- import org.apache.http.client.methods.CloseableHttpResponse;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.client.utils.URIBuilder;
- import org.apache.http.impl.client.CloseableHttpClient;
- import org.apache.http.impl.client.HttpClients;
- import org.apache.http.message.BasicNameValuePair;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import java.net.URISyntaxException;
- import java.text.SimpleDateFormat;
- import java.util.*;
- /**
- * ZaloPay 工具类
- *
- * @author ruoyi
- **/
- @Component
- public class ZaloPay {
- @Autowired
- private ZaloPayApiProperties apiProperties;
- /**
- * 生成 HMAC SHA256 签名
- */
- public static String getCurrentTimeString(String format) {
- Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT+7"));
- SimpleDateFormat fmt = new SimpleDateFormat(format);
- fmt.setCalendar(cal);
- return fmt.format(cal.getTimeInMillis());
- }
- /**
- * 创建ZaloPay订单,返回支付链接
- *
- * @param userId 用户唯一标识
- * @param orderId 订单号(建议格式:yymmdd_唯一编号)
- * @param amount 金额(单位:VND)
- * @param description 订单描述
- * @return ZaloPayCreateOrderResponse 支付响应数据
- */
- public ZaloPayCreateOrderResponse createOrder(String userId, String orderId, long amount, String description,ZaloPayProperties.ZaloPayConfig config) throws Exception {
- // ZaloPayConfig config = ZaloPayConfig.getZaloPayConfig(payType);
- String APP_ID = config.getApp_id();
- String KEY1 = config.getKey1();
- System.out.println("进入zalopay CreateOrder orderId: " + orderId+" amount: " + amount);
- // 从传入参数构建 embed_data
- final Map<String, Object> embed_data = new HashMap<>();
- // 如果有实际需要,可以在这里添加字段
- // 从传入参数构建 item 列表
- final List<Map<String, Object>> items = new ArrayList<>();
- // 示例:添加一个商品项
- Map<String, Object> item = new HashMap<>();
- // item.put("item_price", amount / 100); // 假设金额以分为单位
- // items.add(item);
- String appTransId =getCurrentTimeString("yyMMdd") + "_" + orderId;
- Map<String, Object> order = new HashMap<String, Object>(){{
- put("app_id", APP_ID);
- put("app_trans_id", appTransId);
- put("app_time", System.currentTimeMillis()); //毫米级时间戳,时间戳与时区无关 miliseconds
- put("app_user", userId);
- put("amount", amount);
- put("description", description);
- //钱包支付
- if(config.getPay_type().equals("3")){
- put("bank_code", "zalopayapp");
- put("embed_data", "{}");
- }
- //银行卡支付
- if(config.getPay_type().equals("5")){
- put("bank_code", "");
- put("embed_data", "{\"preferred payment method\":[\"domestic card\",\"account\"],\"redirecturl\":\"cityexpressuser://\"}");
- }
- if(config.getPay_type().equals("4")){
- put("bank_code", "");
- put("embed_data", "{\"preferred payment method\":[\"vietqr\"],\"redirecturl\":\"cityexpressuser://\"}");
- }
- put("item", "[]");
- }};
- String data = order.get("app_id") +"|"+ order.get("app_trans_id") +"|"+ order.get("app_user") +"|"+ order.get("amount")
- +"|"+ order.get("app_time") +"|"+ order.get("embed_data") +"|"+ order.get("item");
- order.put("mac", HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, KEY1, data));
- System.out.println("ZaloPay CreateOrder 创建的 order信息: " + order);
- HttpPost post=createPost(order, apiProperties.getCreate_order_url());
- // 添加日志和异常处理
- try (CloseableHttpClient httpClient = HttpClients.createDefault();
- CloseableHttpResponse res = httpClient.execute(post)) {
- BufferedReader rd = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
- StringBuilder resultJsonStr = new StringBuilder();
- String line;
- while ((line = rd.readLine()) != null) {
- resultJsonStr.append(line);
- }
- String responseJson = resultJsonStr.toString();
- System.out.println("ZaloPay CreateOrder Response: " + responseJson); // 日志输出
- return JSON.parseObject(responseJson, ZaloPayCreateOrderResponse.class);
- }
- }
- /**
- * 查询订单支付状态
- *
- * @param appTransId 订单号
- * @return 支付状态
- */
- public ZaloPayQueryOrderResponse queryOrderStatus(String appTransId,ZaloPayProperties.ZaloPayConfig config) throws URISyntaxException, IOException {
- String APP_ID = config.getApp_id();
- String KEY1 = config.getKey1();
- String data = APP_ID +"|"+ appTransId +"|"+ KEY1; // appid|app_trans_id|key1
- String mac = HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, KEY1, data);
- List<NameValuePair> params = new ArrayList<>();
- params.add(new BasicNameValuePair("app_id", APP_ID));
- params.add(new BasicNameValuePair("app_trans_id", appTransId));
- params.add(new BasicNameValuePair("mac", mac));
- URIBuilder uri = new URIBuilder(apiProperties.getQuery_order_url());
- uri.addParameters(params);
- CloseableHttpClient client = HttpClients.createDefault();
- HttpPost post = new HttpPost(uri.build());
- post.setEntity(new UrlEncodedFormEntity(params));
- CloseableHttpResponse res = client.execute(post);
- BufferedReader rd = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
- StringBuilder resultJsonStr = new StringBuilder();
- String line;
- while ((line = rd.readLine()) != null) {
- resultJsonStr.append(line);
- }
- JSONObject result = JSON.parseObject(resultJsonStr.toString());
- for (String key : result.keySet()) {
- System.out.format("%s = %s\n", key, result.get(key));
- }
- System.out.println("ZaloPay QueryOrder Response: " + resultJsonStr);
- return JSON.parseObject(resultJsonStr.toString(), ZaloPayQueryOrderResponse.class);
- }
- /**
- * 退款
- *
- * @param zpTransId
- * @param amount
- * @return ZaloPayRefundResponse 退款响应数据
- */
- public ZaloPayRefundResponse Refund(String zpTransId, long amount,String mRefundId,ZaloPayProperties.ZaloPayConfig config) throws Exception {
- String APP_ID = config.getApp_id();
- String KEY1 = config.getKey1();
- String appid = APP_ID;
- long timestamp = System.currentTimeMillis(); // miliseconds
- Map<String, Object> order = new HashMap<String, Object>() {{
- put("app_id", appid);
- put("zp_trans_id", zpTransId); // 使用传入的 zpTransId
- // put("m_refund_id", getCurrentTimeString("yyMMdd") + "_" + appid + "_" + ddId);
- put("m_refund_id", mRefundId);
- put("timestamp", timestamp);
- put("amount", amount); // 使用传入的 amount
- put("description", "ZaloPay Intergration Demo");
- }};
- // appid|zptransid|amount|description|timestamp
- String data = order.get("app_id") + "|" + order.get("zp_trans_id") + "|" + order.get("amount")
- + "|" + order.get("description") + "|" + order.get("timestamp");
- order.put("mac", HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, KEY1, data));
- CloseableHttpClient client = HttpClients.createDefault();
- HttpPost post = createPost(order, apiProperties.getRefund_url());
- CloseableHttpResponse res = client.execute(post);
- BufferedReader rd = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
- StringBuilder resultJsonStr = new StringBuilder();
- String line;
- while ((line = rd.readLine()) != null) {
- resultJsonStr.append(line);
- }
- System.out.println("ZaloPay Refund Response: " + resultJsonStr.toString()); // 日志输出
- // 解析响应数据为 ZaloPayRefundResponse 对象
- return JSON.parseObject(resultJsonStr.toString(), ZaloPayRefundResponse.class);
- }
- /**
- * 查询退款状态
- *
- * @param m_refund_id 退款单号
- * @return 退款状态
- */
- public ZaloPayQueryRefundResponse queryRefundStatus(String m_refund_id, ZaloPayProperties.ZaloPayConfig config) throws URISyntaxException, IOException {
- String APP_ID = config.getApp_id();
- String KEY1 = config.getKey1();
- String timestamp = Long.toString(System.currentTimeMillis()); // miliseconds
- String data = APP_ID +"|"+ m_refund_id +"|"+ timestamp; // app_id|m_refund_id|timestamp
- String mac = HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, KEY1, data);
- List<NameValuePair> params = new ArrayList<>();
- params.add(new BasicNameValuePair("app_id", APP_ID));
- params.add(new BasicNameValuePair("m_refund_id", m_refund_id));
- params.add(new BasicNameValuePair("timestamp", timestamp));
- params.add(new BasicNameValuePair("mac", mac));
- URIBuilder uri = new URIBuilder(apiProperties.getQuery_refund_url());
- uri.addParameters(params);
- CloseableHttpClient client = HttpClients.createDefault();
- HttpPost post = new HttpPost(uri.build());
- post.setEntity(new UrlEncodedFormEntity(params));
- CloseableHttpResponse res = client.execute(post);
- BufferedReader rd = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
- StringBuilder resultJsonStr = new StringBuilder();
- String line;
- while ((line = rd.readLine()) != null) {
- resultJsonStr.append(line);
- }
- System.out.println("ZaloPay QueryRefund Response: " + resultJsonStr);
- return JSON.parseObject(resultJsonStr.toString(), ZaloPayQueryRefundResponse.class);
- }
- public static HttpPost createPost(Map<String, Object> order, String refundUrl) throws UnsupportedEncodingException {
- HttpPost post = new HttpPost(refundUrl);
- List<NameValuePair> params = new ArrayList<>();
- for (Map.Entry<String, Object> e : order.entrySet()) {
- params.add(new BasicNameValuePair(e.getKey(), e.getValue().toString()));
- }
- post.setEntity(new UrlEncodedFormEntity(params));
- return post;
- }
- }
|