package com.stylefeng.guns.modular.system.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.springframework.util.StringUtils; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.*; /** * 创博优支付工具类 * 目前仅实现创建支付单接口。 */ public class CbyzxPayUtil { /** * 测试环境域名 */ public static final String TEST_BASE_URL = "https://test-api-pay.cbyzx.com"; /** * 创建支付单接口 */ public static final String CREATE_PAY_ORDER_PATH = "/api/inner/pay/create"; public static final String CLOSE_PAY_ORDER_PATH = "/api/inner/pay/close"; private static final String PAYMENT_ORDER_TYPE = "PAYMENT_ORDER"; private static final String DEFAULT_CURRENCY = "CNY"; private static final String DEFAULT_PAY_CHANNEL_CODE = "ykdride-wxmini"; private static final String DEFAULT_TENANT = "gz.zuny.ykdride.platform"; private CbyzxPayUtil() { } /** * 创建支付单 * * @param request 请求参数 * @return 接口响应 */ public static JSONObject createPayOrder(CreatePayOrderRequest request) { return createPayOrder(TEST_BASE_URL, request); } /** * 创建支付单 * * @param baseUrl 域名 * @param request 请求参数 * @return 接口响应 */ public static JSONObject createPayOrder(String baseUrl, CreatePayOrderRequest request) { validateCreatePayOrderRequest(request); return postForJson(baseUrl, CREATE_PAY_ORDER_PATH, request.toParamMap(), "create pay order"); } /** * * 关闭支付单 * @param request * @return */ public static JSONObject closePayOrder(ClosePayOrderRequest request) { return closePayOrder(TEST_BASE_URL, request); } public static JSONObject closePayOrder(String baseUrl, ClosePayOrderRequest request) { validateClosePayOrderRequest(request); return postForJson(baseUrl, CLOSE_PAY_ORDER_PATH, request.toParamMap(), "close pay order"); } private static JSONObject postForJson(String baseUrl, String path, Map params, String actionName) { HttpClientUtil httpClientUtil = new HttpClientUtil(); String responseText = httpClientUtil.pushHttpRequset( "POST", buildUrl(baseUrl, path), params, buildJsonHeader(), "json" ); if (!StringUtils.hasText(responseText)) { throw new IllegalStateException(actionName + " failed: empty response"); } try { return JSON.parseObject(responseText); } catch (Exception ex) { JSONObject result = new JSONObject(); result.put("success", false); result.put("rawResponse", responseText); result.put("message", "response is not json"); return result; } } private static Map buildJsonHeader() { Map header = new LinkedHashMap<>(); header.put("Content-Type", "application/json;charset=UTF-8"); header.put("Accept", "application/json"); return header; } private static String buildUrl(String baseUrl, String path) { String finalBaseUrl = baseUrl; if (!StringUtils.hasText(finalBaseUrl)) { finalBaseUrl = TEST_BASE_URL; } if (finalBaseUrl.endsWith("/")) { finalBaseUrl = finalBaseUrl.substring(0, finalBaseUrl.length() - 1); } return finalBaseUrl + path; } private static void validateCreatePayOrderRequest(CreatePayOrderRequest request) { if (request == null) { throw new IllegalArgumentException("request must not be null"); } if (!StringUtils.hasText(request.getTenant())) { throw new IllegalArgumentException("tenant must not be blank"); } if (!StringUtils.hasText(request.getPaymentOrderType())) { throw new IllegalArgumentException("paymentOrderType must not be blank"); } if (!StringUtils.hasText(request.getOutRequestNo())) { throw new IllegalArgumentException("outRequestNo must not be blank"); } if (request.getPaymentOrderAmount() == null) { throw new IllegalArgumentException("paymentOrderAmount must not be null"); } if (!StringUtils.hasText(request.getCurrency())) { throw new IllegalArgumentException("currency must not be blank"); } if (request.getBuyerId() == null) { throw new IllegalArgumentException("buyerId must not be null"); } if (!StringUtils.hasText(request.getOpenId())) { throw new IllegalArgumentException("openId must not be blank"); } if (request.getStoreIds().isEmpty()) { throw new IllegalArgumentException("storeIds must not be blank"); } if (!StringUtils.hasText(request.getPayChannelCode())) { throw new IllegalArgumentException("payChannelCode must not be blank"); } if (!StringUtils.hasText(request.getPayEndTime())) { throw new IllegalArgumentException("payEndTime must not be blank"); } if (!StringUtils.hasText(request.getCallbackUrl())) { throw new IllegalArgumentException("callbackUrl must not be blank"); } } private static void validateClosePayOrderRequest(ClosePayOrderRequest request) { if (request == null) { throw new IllegalArgumentException("request must not be null"); } if (!StringUtils.hasText(request.getTenant())) { throw new IllegalArgumentException("tenant must not be blank"); } if (!StringUtils.hasText(request.getOutRequestNo())) { throw new IllegalArgumentException("outRequestNo must not be blank"); } } /** * 构造一份本地测试数据 */ public static CreatePayOrderRequest mockRequest() { CreatePayOrderRequest request = new CreatePayOrderRequest(); request.setTenant(DEFAULT_TENANT); request.setPaymentOrderType(PAYMENT_ORDER_TYPE); request.setOutRequestNo("TEST" + System.currentTimeMillis()); request.setPaymentOrderAmount(new BigDecimal("100")); request.setCurrency(DEFAULT_CURRENCY); request.setBuyerId(10001L); request.setOpenId("oMockOpenId123456789"); request.setStoreIds(Arrays.asList("246")); request.setPayChannelCode(DEFAULT_PAY_CHANNEL_CODE); request.setPayEndTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis() + 30L * 60L * 1000L))); request.setCallbackUrl("http://127.0.0.1:8080/pay/mockCallback"); return request; } public static ClosePayOrderRequest mockCloseRequest(String outRequestNo) { ClosePayOrderRequest request = new ClosePayOrderRequest(); request.setTenant(DEFAULT_TENANT); request.setOutRequestNo(outRequestNo); return request; } public static void main(String[] args) { CreatePayOrderRequest request = mockRequest(); System.out.println("request url: " + buildUrl(TEST_BASE_URL, CREATE_PAY_ORDER_PATH)); System.out.println("request body: " + JSON.toJSONString(request.toParamMap(), true)); try { JSONObject response = createPayOrder(request); System.out.println("response body: " + JSON.toJSONString(response, true)); } catch (Exception ex) { System.err.println("request failed: " + ex.getMessage()); ex.printStackTrace(); } } /** * 创建支付单请求参数 */ public static class CreatePayOrderRequest { private String tenant; private String paymentOrderType; private String outRequestNo; private BigDecimal paymentOrderAmount; private String currency; private Long buyerId; private String openId; private List storeIds; private String payChannelCode; private String payEndTime; private String callbackUrl; public Map toParamMap() { Map params = new LinkedHashMap<>(); params.put("tenant", tenant); params.put("paymentOrderType", paymentOrderType); params.put("outRequestNo", outRequestNo); params.put("paymentOrderAmount", paymentOrderAmount); params.put("currency", currency); params.put("buyerId", buyerId); params.put("openId", openId); params.put("storeIds", storeIds); params.put("payChannelCode", payChannelCode); params.put("payEndTime", payEndTime); params.put("callbackUrl", callbackUrl); return params; } public String getTenant() { return tenant; } public void setTenant(String tenant) { this.tenant = tenant; } public String getPaymentOrderType() { return paymentOrderType; } public void setPaymentOrderType(String paymentOrderType) { this.paymentOrderType = paymentOrderType; } public String getOutRequestNo() { return outRequestNo; } public void setOutRequestNo(String outRequestNo) { this.outRequestNo = outRequestNo; } public BigDecimal getPaymentOrderAmount() { return paymentOrderAmount; } public void setPaymentOrderAmount(BigDecimal paymentOrderAmount) { this.paymentOrderAmount = paymentOrderAmount; } public String getCurrency() { return currency; } public void setCurrency(String currency) { this.currency = currency; } public Long getBuyerId() { return buyerId; } public void setBuyerId(Long buyerId) { this.buyerId = buyerId; } public String getOpenId() { return openId; } public void setOpenId(String openId) { this.openId = openId; } public List getStoreIds() { return storeIds; } public void setStoreIds(List storeIds) { this.storeIds = storeIds; } public String getPayChannelCode() { return payChannelCode; } public void setPayChannelCode(String payChannelCode) { this.payChannelCode = payChannelCode; } public String getPayEndTime() { return payEndTime; } public void setPayEndTime(String payEndTime) { this.payEndTime = payEndTime; } public String getCallbackUrl() { return callbackUrl; } public void setCallbackUrl(String callbackUrl) { this.callbackUrl = callbackUrl; } } public static class ClosePayOrderRequest { private String tenant; private String outRequestNo; public Map toParamMap() { Map params = new LinkedHashMap<>(); params.put("tenant", tenant); params.put("outRequestNo", outRequestNo); return params; } public String getTenant() { return tenant; } public void setTenant(String tenant) { this.tenant = tenant; } public String getOutRequestNo() { return outRequestNo; } public void setOutRequestNo(String outRequestNo) { this.outRequestNo = outRequestNo; } } }