|
@@ -0,0 +1,269 @@
|
|
|
+package com.xc.utils.pay;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.xc.utils.PropertiesUtil;
|
|
|
+import org.apache.commons.codec.digest.DigestUtils;
|
|
|
+import org.apache.http.HttpEntity;
|
|
|
+import org.apache.http.HttpResponse;
|
|
|
+import org.apache.http.HttpStatus;
|
|
|
+import org.apache.http.client.HttpClient;
|
|
|
+import org.apache.http.client.methods.HttpPost;
|
|
|
+import org.apache.http.entity.StringEntity;
|
|
|
+import org.apache.http.impl.client.HttpClientBuilder;
|
|
|
+import org.apache.http.util.EntityUtils;
|
|
|
+
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+public class GpayUtil {
|
|
|
+
|
|
|
+ //公户
|
|
|
+ final static String UID = PropertiesUtil.getProperty("gpay.uid");
|
|
|
+ final static String MCHID = PropertiesUtil.getProperty("gpay.mchid");
|
|
|
+ final static String SECRET = PropertiesUtil.getProperty("gpay.secret");
|
|
|
+ final static String ORDER_URL= PropertiesUtil.getProperty("gpay.url") + "/payapi/v3/orders";
|
|
|
+ final static String NOTIFY_URL= PropertiesUtil.getProperty("gpay.notify.url");
|
|
|
+ //私户
|
|
|
+ final static String UID2 = PropertiesUtil.getProperty("gpay.uid2");
|
|
|
+ final static String MCHID2 = PropertiesUtil.getProperty("gpay.mchid2");
|
|
|
+ final static String SECRET2 = PropertiesUtil.getProperty("gpay.secret2");
|
|
|
+
|
|
|
+
|
|
|
+ final static String shopid365 = PropertiesUtil.getProperty("gpay.shopid");
|
|
|
+ final static String key365 = PropertiesUtil.getProperty("gpay.key");
|
|
|
+ final static String return_url365 = PropertiesUtil.getProperty("gpay.return_url");
|
|
|
+ final static String callback_url365 = PropertiesUtil.getProperty("gpay.callback_url");
|
|
|
+ final static String url365 = PropertiesUtil.getProperty("gpay.url365");
|
|
|
+
|
|
|
+
|
|
|
+// public static void main(String[] args) {
|
|
|
+// Map<String, Object> map = new HashMap<String, Object>();
|
|
|
+// map.put("uid", UID);
|
|
|
+// map.put("mchid", MCHID);
|
|
|
+// map.put("mch_orderid", "test123456");
|
|
|
+// map.put("amount", "10.00");
|
|
|
+// map.put("channel", "300"); // 100 支付寶 200 微信 300 銀行卡; 開通請聯繫運營
|
|
|
+// map.put("notify_url", "http://0.0.0.0:8081/test/notify"); // 回調地址
|
|
|
+// map.put("return_url", "http://0.0.0.0:8081/test/return"); // 支付成功後跳轉地址
|
|
|
+// map.put("product_name", "商品1");
|
|
|
+// map.put("member_name", "會員1");
|
|
|
+// map.put("extra", "透傳");
|
|
|
+// map.put("timestamp", "2020-12-17 13:18:36");
|
|
|
+// // 签名
|
|
|
+// String sign = sign(map, SECRET);
|
|
|
+// JSONObject json = new JSONObject(map);
|
|
|
+// json.put("sign", sign);
|
|
|
+// // 下单
|
|
|
+// JSONObject response = doPost(ORDER_URL, json);
|
|
|
+// System.out.println("ORDER_URL: "+ORDER_URL);
|
|
|
+// System.out.println("response: "+response);
|
|
|
+// // 回调
|
|
|
+// String data = "{'tradeid':'5fc49d05e5bf59cbad7f92ec', 'uid':'5fc4843fe5bf59cbad7f8ff2', 'mchid':'5fc4843fe5bf59cbad7f8ff3', 'mch_orderid':'123','channel':'300', 'currency':'CNY', 'amount':'10.00', 'timestamp':'2020-11-30 15:20:41', 'extra':'透傳', 'status':'success', 'sign':'3a2ac4dfc1456c2301b2227d6b303045'}";
|
|
|
+// notify(data);
|
|
|
+// }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+// JSONObject jb = gPay("19.00" , "778899" , "55555");
|
|
|
+// System.out.println(jb.getString("msg"));
|
|
|
+// JSONObject data = (JSONObject) jb.get("data");
|
|
|
+// JSONObject jbb = JSON.parseObject(data.getString("result"));
|
|
|
+// System.out.println(jbb.getString("url"));
|
|
|
+
|
|
|
+// JSONArray result = data.getJSONArray("result");
|
|
|
+// String url = (String)jb.get("result");
|
|
|
+// System.out.println(result);
|
|
|
+// String data = "{'tradeid':'5fdb22d04ff77f70fef29523', 'uid':'5fc5ae01ae8c2dea7a6eea55', 'mchid':'5fc5ae01ae8c2dea7a6eea56', 'mch_orderid':'778899','channel':'300', 'amount':'19.00', 'timestamp':'2020-12-17 17:20:17', 'extra':'extra', 'status':'success', 'sign':'2c87ce12af764362115f442b0a596cc2'}";
|
|
|
+// JSONObject json = JSONObject.parseObject(data);
|
|
|
+// Map<String, Object> map = (Map<String, Object>) json;
|
|
|
+// String sign = sign(map, SECRET);
|
|
|
+//
|
|
|
+ //回调
|
|
|
+// if (!map.get("sign").toString().equals(sign)) {
|
|
|
+// System.out.println("签名不一致:"+map.get("sign").toString());
|
|
|
+// }
|
|
|
+
|
|
|
+// notify365("{\"order_status\":4,\"amount\":\"110.00\",\"orderno\":\"21123\",\"seller_name\":\"200\",\"price\":\"6.56\",\"qty\":\"16.768292\",\"sign\":\"D55BF386C8E1DC24151B014E915DCB70\",\"buyer_name\":\"无\"}");
|
|
|
+
|
|
|
+// gPay365("130.00","202012241515","测试12241514","1211");
|
|
|
+ }
|
|
|
+
|
|
|
+ public static JSONObject gPay(String amount , String ordersn , String phone){
|
|
|
+ Map<String, Object> map = new HashMap();
|
|
|
+ map.put("uid", UID);
|
|
|
+ map.put("mchid", MCHID);
|
|
|
+ map.put("mch_orderid", ordersn);
|
|
|
+ map.put("amount", amount);
|
|
|
+ map.put("channel", "300");
|
|
|
+ map.put("notify_url", NOTIFY_URL);
|
|
|
+ map.put("member_name", phone);
|
|
|
+ map.put("extra", "extra");
|
|
|
+ map.put("timestamp", generateTime());
|
|
|
+ // 签名
|
|
|
+ String sign = sign(map, SECRET);
|
|
|
+ JSONObject json = new JSONObject(map);
|
|
|
+ json.put("sign", sign);
|
|
|
+// System.out.println("uid:" + UID);
|
|
|
+// System.out.println("mchid:" + MCHID);
|
|
|
+// System.out.println("notify_url:" + NOTIFY_URL);
|
|
|
+// System.out.println("SECRET:" + SECRET);
|
|
|
+ // 下单
|
|
|
+ JSONObject response = doPost(ORDER_URL, json);
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static JSONObject gPay2(String amount , String ordersn , String phone){
|
|
|
+ Map<String, Object> map = new HashMap();
|
|
|
+ map.put("uid", UID2);
|
|
|
+ map.put("mchid", MCHID2);
|
|
|
+ map.put("mch_orderid", ordersn);
|
|
|
+ map.put("amount", amount);
|
|
|
+ map.put("channel", "300");
|
|
|
+ map.put("notify_url", NOTIFY_URL);
|
|
|
+ map.put("member_name", phone);
|
|
|
+ map.put("extra", "extra");
|
|
|
+ map.put("timestamp", generateTime());
|
|
|
+ // 签名
|
|
|
+ String sign = sign(map, SECRET2);
|
|
|
+ JSONObject json = new JSONObject(map);
|
|
|
+ json.put("sign", sign);
|
|
|
+ // 下单
|
|
|
+ JSONObject response = doPost(ORDER_URL, json);
|
|
|
+// System.out.println(response.toString());
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+
|
|
|
+ // sign
|
|
|
+ public static String sign(Map<String, Object> map, String signKey) {
|
|
|
+ if (map == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<String> keyList = new ArrayList<>(map.keySet());
|
|
|
+ Collections.sort(keyList);
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ for (int i = 0; i < keyList.size(); i++) {
|
|
|
+ String key = keyList.get(i);
|
|
|
+ Object value = map.get(key);
|
|
|
+ if (key.equals("sign") || value.equals("")) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ sb.append(key + "=" + value + "&");
|
|
|
+ }
|
|
|
+ String signStr = sb.substring(0, sb.length() - 1) + signKey;
|
|
|
+// System.out.println("before sign: " + signStr);
|
|
|
+ String md5Str = DigestUtils.md5Hex(signStr);
|
|
|
+// System.out.println("after sign: " + md5Str);
|
|
|
+ return md5Str;
|
|
|
+ }
|
|
|
+
|
|
|
+ // http request
|
|
|
+ public static JSONObject doPost(String url, JSONObject jsonObject) {
|
|
|
+ HttpClient client = HttpClientBuilder.create().build();
|
|
|
+ HttpPost post = new HttpPost(url);
|
|
|
+ JSONObject response = null;
|
|
|
+ try {
|
|
|
+ StringEntity s = new StringEntity(jsonObject.toString(), "utf-8");
|
|
|
+ s.setContentType("application/json;utf-8");
|
|
|
+ post.setEntity(s);
|
|
|
+ HttpResponse res = client.execute(post);
|
|
|
+ HttpEntity entity = res.getEntity();
|
|
|
+ String result = EntityUtils.toString(entity);
|
|
|
+ response = JSONObject.parseObject(result);
|
|
|
+ if (res.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
|
|
+ throw new Error(response.toJSONString());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 回调通知
|
|
|
+ public String notify(String data) {
|
|
|
+ System.out.println(data);
|
|
|
+ JSONObject json = JSONObject.parseObject(data);
|
|
|
+ Map<String, Object> map = (Map<String, Object>) json;
|
|
|
+ System.out.println(json.toString());
|
|
|
+ System.out.println(map.toString());
|
|
|
+ // 验证签名
|
|
|
+ String sign = sign(map, SECRET);
|
|
|
+ if (!map.get("sign").toString().equals(sign)) {
|
|
|
+ System.out.println("签名不一致:"+map.get("sign").toString());
|
|
|
+ return "签名不一致";
|
|
|
+ }
|
|
|
+ String amount = map.get("amount").toString();
|
|
|
+ String orderSn = map.get("mch_orderid").toString();
|
|
|
+ String tradeid = map.get("tradeid").toString();
|
|
|
+ System.out.println(amount +"@" + orderSn +"@"+ tradeid);
|
|
|
+ try {
|
|
|
+ }catch (Exception e){
|
|
|
+ return "fail";
|
|
|
+ }
|
|
|
+ // TODO: timestamp, 如回调超时N小时后,是否处理依据具体业务
|
|
|
+ return "success";
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String generateTime() {
|
|
|
+ return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /*--------- pay365 相关接口Start------------ */
|
|
|
+
|
|
|
+ // 回调通知 验证签名
|
|
|
+ public static String notify365(String data) {
|
|
|
+ JSONObject json = JSONObject.parseObject(data);
|
|
|
+ Map<String, Object> map = (Map<String, Object>) json;
|
|
|
+ // 验证签名
|
|
|
+ return getPay365Sign(map, key365);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static JSONObject gPay365(String amount,String ordersn , String phone,String userid){
|
|
|
+ Map<String, Object> map = new HashMap();
|
|
|
+ map.put("amount", amount); // 金额
|
|
|
+ map.put("kyc_name", phone); // 姓名 -
|
|
|
+ map.put("orderno", ordersn); // 订单号 mch_orderid
|
|
|
+ map.put("shopid", shopid365); // 商户id
|
|
|
+ map.put("exid", userid); //买家id
|
|
|
+ map.put("return_url", return_url365); //订单完成后跳转地址
|
|
|
+ map.put("callback_url",callback_url365); //异步回调地址
|
|
|
+ // 签名
|
|
|
+ String sign = getPay365Sign(map, key365);
|
|
|
+ map.put("sign", sign);
|
|
|
+ JSONObject json = new JSONObject(map);
|
|
|
+ JSONObject response = doPost(url365, json);
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static String getPay365Sign(Map<String ,Object> $params , String key){
|
|
|
+ String $signData = ksort($params);
|
|
|
+ $signData = $signData+"&key="+key;
|
|
|
+ $signData = DigestUtils.md5Hex($signData);
|
|
|
+ $signData = $signData.toUpperCase();
|
|
|
+ return $signData ;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String ksort(Map<String, Object> map) {
|
|
|
+ List<String> keyList = new ArrayList<>(map.keySet());
|
|
|
+ Collections.sort(keyList);
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ for (int i = 0; i < keyList.size(); i++) {
|
|
|
+ String key = keyList.get(i);
|
|
|
+ Object value = map.get(key);
|
|
|
+ if (key.equals("sign")) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ sb.append(key + "=" + value + "&");
|
|
|
+ }
|
|
|
+ return sb.toString().substring(0, sb.toString().length() - 1) ;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /*--------- pay365 相关接口end ------------ */
|
|
|
+}
|