不好说,通联接口取的名字给我整迷糊了。。。
通联接口文档:通联支付-通商云开放平台
一、配置
首先你要创建他们的会员,还要绑定银行卡,这一步不讲,我们主要讲支付流程
1、基础配置
yml配置
# 通联支付数据获取
allinpay:
serverUrl: https://open.allinpay.com/gateway
appId: 1...42
secretKey: o...i
privateKeyPath: E:\...\168...(RSA2).pfx
tlPublicKey: E:\...\TLCert.cer
sysId: 5...2
number: 4...8
需要申请通联支付的密钥和证书
对应实体类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "allinpay")
public class AllinPayConfig {
private String serverUrl;
private String appId;
private String secretKey;
private String privateKeyPath;
private String tlPublicKey;
private String sysId;
private String number;
}
2、通联demo
package org.dromara.pay.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.allinpay.sdk.OpenClient;
import com.allinpay.sdk.bean.BizParameter;
import com.allinpay.sdk.bean.OpenConfig;
import com.allinpay.sdk.bean.OpenResponse;
import jodd.util.StringUtil;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.pay.config.AllinPayConfig;
import org.dromara.pay.domain.params.*;
import org.dromara.system.api.RemoteConfigService;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
public class AllinPayUtils {
private final AllinPayConfig config;
private final AllinPayConfig allinPayConfig;
@DubboReference
private RemoteConfigService configService;
// 定义客户端
public AllinPayUtils(AllinPayConfig config, RemoteConfigService configService, AllinPayConfig allinPayConfig) {
this.config = config;
this.configService = configService;
this.allinPayConfig = allinPayConfig;
}
/**
* 初始化OpenClient
*
* @return
*/
public OpenClient configClient() {
final String url = config.getServerUrl();
final String appId = config.getAppId();
final String secretKey = config.getSecretKey();
final String privateKeyPath = config.getPrivateKeyPath();
final String pwd = "123456";
final String tlPublicKey = config.getTlPublicKey();
final OpenConfig oc = new OpenConfig(url, appId, secretKey, privateKeyPath, pwd, tlPublicKey);
OpenClient openClient = new OpenClient(oc);
try {
openClient = new OpenClient(oc);
} catch (final Exception e) {
e.printStackTrace();
}
return openClient;
}
/**
* 公共请求返回函数
*
* @param method
* @param param
* @return
*/
private OpenResponse returnClient(String method, BizParameter param) {
OpenClient client = configClient();
OpenResponse response = null;
try {
response = client.execute(method, param);
} catch (final Exception e) {
e.printStackTrace();
}
return response;
}
/**
* 解密
*/
public String decrypt(String encryptStr) {
OpenClient client = configClient();
String decryptStr = "";
try {
decryptStr = client.decrypt(encryptStr);
} catch (final Exception e) {
e.printStackTrace();
}
return decryptStr;
}
/**
* 公共请求返回函数
*
* @param method
* @param param
* @return
*/
private String concatUrlParams(String method, BizParameter param) {
OpenClient client = configClient();
String url = "";
try {
url = client.concatUrlParams(method, param);
} catch (final Exception e) {
e.printStackTrace();
}
return url;
}
/**
* ---------------------------------------- 会员接口 开始 -----------------------------------------------
*/
/**
* 通联支付 创建会员
*
* @param bizUserId
* @return
*/
public OpenResponse createMember(String bizUserId, String memberType) {
String method = "allinpay.yunst.memberService.createMember";
BizParameter param = new BizParameter();
param.put("bizUserId", bizUserId);
param.put("memberType", Long.parseLong(memberType));
param.put("source", 1L);
return returnClient(method, param);
}
/**
* 通联支付 查询会员信息
*
* @param bizUserId
* @return
*/
public OpenResponse getMemberInfo(String bizUserId) {
String method = "allinpay.yunst.memberService.getMemberInfo";
BizParameter param = new BizParameter();
param.put("bizUserId", bizUserId);
return returnClient(method, param);
}
/**
* 通联支付 设置企业信息
* @param params 设置企业信息表单参数
* @return
*/
public OpenResponse setCompanyInfo(CompanyInfoParams params) {
OpenClient client = configClient();
String method = "allinpay.yunst.memberService.setCompanyInfo";
BizParameter param = new BizParameter();
// 组装企业信息
param.put("bizUserId", params.getBizUserId());
param.put("comproperty", params.getComproperty());
//param.put("backUrl", "http://www.baidu.com");
//param.put("isAuth", false);
final Map<String, Object> companyBasicInfo = new LinkedHashMap<>();
companyBasicInfo.put("companyName", params.getCompanyName());
companyBasicInfo.put("companyAddress", params.getCompanyAddress());
companyBasicInfo.put("authType", Long.parseLong(params.getAuthType()));
if ("1".equals(params.getAuthType())){//认证类型 三证
companyBasicInfo.put("businessLicense", params.getBusinessLicense());//营业执照号
companyBasicInfo.put("organizationCode", params.getOrganizationCode());//组织机构代码
companyBasicInfo.put("taxRegister", params.getTaxRegister());//税务登记证
}else if ("2".equals(params.getAuthType())){//认证类型 一证 统一社会信用
companyBasicInfo.put("uniCredit", params.getUniCredit());
}
companyBasicInfo.put("expLicense", params.getExpLicense());
companyBasicInfo.put("acctType", Long.parseLong(params.getAcctType()));
if ("0".equals(params.getAcctType())){//对私账户
companyBasicInfo.put("phone", params.getPhone());
} else if ("1".equals(params.getAcctType())) {//对公账户
companyBasicInfo.put("parentBankName", params.getParentBankName());
companyBasicInfo.put("bankName", params.getBankName());
companyBasicInfo.put("unionBank", params.getUnionBank());
}
companyBasicInfo.put("telephone", params.getTelephone());
companyBasicInfo.put("legalName", params.getLegalName());
companyBasicInfo.put("identityType", Long.parseLong(params.getIdentityType()));
companyBasicInfo.put("legalIds", client.encrypt(params.getLegalIds()));
companyBasicInfo.put("legalPhone", params.getLegalPhone());
companyBasicInfo.put("accountNo", client.encrypt(params.getAccountNo()));
companyBasicInfo.put("bankCityNo", params.getBankCityNo());
companyBasicInfo.put("province", params.getProvince());
companyBasicInfo.put("city", params.getCity());
param.put("companyBasicInfo", companyBasicInfo);
return returnClient(method, param);
}
/**
* 通联支付 锁定会员
*
* @param bizUserId 商户系统用户标识
* @return
*/
public OpenResponse lockMember(String bizUserId) {
String method = "allinpay.yunst.memberService.lockMember";
BizParameter param = new BizParameter();
param.put("bizUserId", bizUserId);
return returnClient(method, param);
}
/**
* 通联支付 解锁会员
*
* @param bizUserId
* @return
*/
public OpenResponse unlockMember(String bizUserId) {
String method = "allinpay.yunst.memberService.unlockMember";
BizParameter param = new BizParameter();
param.put("bizUserId", bizUserId);
return returnClient(method, param);
}
/**
* 通联支付 发送验证码
*
* @param bizUserId 商户系统用户标识
* @param phone 手机号码
* @param verificationCodeType 验证码类型 9-绑定手机,6-解绑手机
* @return
*/
public OpenResponse sendVerificationCode(String bizUserId, String phone, Long verificationCodeType) {
String method = "allinpay.yunst.memberService.sendVerificationCode";
BizParameter param = new BizParameter();
param.put("bizUserId", bizUserId);
param.put("phone", phone);
param.put("verificationCodeType", verificationCodeType);
return returnClient(method, param);
}
/**
* 通联支付 会员绑定手机
*
* @param params
* @return
*/
public OpenResponse bindPhone(BindPhoneParams params) {
String method = "allinpay.yunst.memberService.bindPhone";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("phone", params.getPhone());
param.put("verificationCode", params.getVerificationCode());
return returnClient(method, param);
}
/**
* 通联支付 会员解除绑定手机(根据原手机验证码)
*
* @param params
* @return
*/
public OpenResponse unbindPhone(BindPhoneParams params) {
String method = "allinpay.yunst.memberService.unbindPhone";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("phone", params.getPhone());
param.put("verificationCode", params.getVerificationCode());
return returnClient(method, param);
}
/**
* 通联支付 实名认证
*
* @param params 会员实名认证表单类
* @return
*/
public OpenResponse setRealName(SetRealNameParams params) {
OpenClient client = configClient();
String method = "allinpay.yunst.memberService.setRealName";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("name", params.getName());
param.put("identityType", params.getIdentityType());
param.put("identityNo", client.encrypt(params.getIdentityNo()));
if (!StringUtil.isEmpty(params.getIdentityBeginDate())) {
param.put("identityBeginDate", params.getIdentityBeginDate());
}
if (!StringUtil.isEmpty(params.getIdentityEndDate())) {
param.put("identityEndDate", params.getIdentityEndDate());
}
if (!StringUtil.isEmpty(params.getAddress())) {
param.put("address", params.getAddress());
}
if (!StringUtil.isEmpty(params.getProfessionNo())) {
param.put("professionNo", params.getProfessionNo());
}
if (!StringUtil.isEmpty(params.getTelephone())) {
param.put("telephone", params.getTelephone());
}
return returnClient(method, param);
}
/**
* 通联支付 会员绑定支付账户用户标识
*
* @param params 会员绑定支付账户用户标识 表单类
* @return
*/
public OpenResponse applyBindAcct(ApplyBindAcctParams params) {
String method = "allinpay.yunst.memberService.applyBindAcct";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("operationType", params.getOperationType());
if ("set".equals(params.getOperationType())) {
param.put("acctType", params.getAcctType());
param.put("acct", params.getAcct());
}
return returnClient(method, param);
}
/**
* 通联支付 设置支付密码
*
* @param params 会员设置支付密码表单类
* @return
*/
public String setPayPwd(SetPayPwdParams params) {
OpenClient client = configClient();
String method = "allinpay.yunst.memberService.setPayPwd";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("phone", params.getPhone());
param.put("identityType", params.getIdentityType());
param.put("identityNo", client.encrypt(params.getIdentityNo()));
param.put("backUrl", params.getBackUrl());
if (!StringUtil.isEmpty(params.getName())) {
param.put("name", params.getName());
}
if (!StringUtil.isEmpty(params.getJumpPageType())) {
param.put("jumpPageType", params.getJumpPageType());
}
if (!StringUtil.isEmpty(params.getJumpUrl())) {
param.put("jumpUrl", params.getJumpUrl());
}
String url = "";
try {
url = client.concatUrlParams(method, param);
} catch (final Exception e) {
e.printStackTrace();
}
return url;
}
/**
* 通联支付 请求绑定银行卡
*
* @param params 会员请求绑定银行卡表单类
* @return
*/
public OpenResponse applyBindBankCard(ApplyBindBankCardParams params) {
OpenClient client = configClient();
String method = "allinpay.yunst.memberService.applyBindBankCard";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("cardNo", client.encrypt(params.getCardNo()));
param.put("phone", params.getPhone());
param.put("name", params.getName());
param.put("cardCheck", params.getCardCheck());
param.put("identityType", params.getIdentityType());
param.put("identityNo", client.encrypt(params.getIdentityNo()));
if (!StringUtil.isEmpty(params.getValidate())) {
param.put("validate", client.encrypt(params.getValidate()));
}
if (!StringUtil.isEmpty(params.getValidate())) {
param.put("cvv2", client.encrypt(params.getCvv2()));
}
param.put("unionBank", params.getUnionBank());
return returnClient(method, param);
}
/**
* 通联支付 确认绑定银行卡
*
* @param params 会员确认绑定银行卡表单类
* @return
*/
public OpenResponse bindBankCard(BindBankCardParams params) {
OpenClient client = configClient();
String method = "allinpay.yunst.memberService.bindBankCard";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("phone", params.getPhone());
param.put("verificationCode", params.getVerificationCode());
param.put("tranceNum", params.getTranceNum());
param.put("transDate", params.getTransDate());
if (!StringUtil.isEmpty(params.getValidate())) {
param.put("validate", client.encrypt(params.getValidate()));
}
if (!StringUtil.isEmpty(params.getValidate())) {
param.put("cvv2", client.encrypt(params.getCvv2()));
}
return returnClient(method, param);
}
/**
* 通联支付 查询绑定银行卡
*
* @param bizUserId 商户系统用户标识
* @param cardNo 银行卡号。如为空,则返回用户所有绑定银行卡。
* @return
*/
public OpenResponse queryBankCard(String bizUserId, String cardNo) {
OpenClient client = configClient();
String method = "allinpay.yunst.memberService.queryBankCard";
BizParameter param = new BizParameter();
param.put("bizUserId", bizUserId);
if (!StringUtil.isEmpty(cardNo)) {
param.put("cardNo", client.encrypt(cardNo));
}
return returnClient(method, param);
}
/**
* 通联支付 解除绑定银行卡
*
* @param bizUserId 商户系统用户标识
* @param cardNo 银行卡号
* @param agreementNo
* @return
*/
public OpenResponse unbindBankCard(String bizUserId, String cardNo, String agreementNo) {
OpenClient client = configClient();
String method = "allinpay.yunst.memberService.unbindBankCard";
BizParameter param = new BizParameter();
param.put("bizUserId", bizUserId);
if (!StringUtil.isEmpty(cardNo)) {
param.put("cardNo", client.encrypt(cardNo));
}
if (!StringUtil.isEmpty(agreementNo)) {
param.put("agreementNo", agreementNo);
}
return returnClient(method, param);
}
/**
* 通联支付 账户提现协议签约
*
* @param bizUserId 商户系统用户标识
* @return
*/
public String signAcctProtocol(String bizUserId) {
OpenClient client = configClient();
String method = "allinpay.yunst.memberService.signAcctProtocol";
BizParameter param = new BizParameter();
OpenResponse response = getMemberInfo(bizUserId);
if (response != null) {
if ("OK".equals(response.getSubCode())) {
JSONObject data = JSON.parseObject(response.getData());
JSONObject infoObject = data.getJSONObject("memberInfo");
String name = infoObject.getString("name");
param.put("signAcctName", name);
}
}
param.put("bizUserId", bizUserId);
String backUrl = String.valueOf(configService.selectRegisterEnabled("allinPay.sign.backUrl"));
String regex = "\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(backUrl);
boolean isMatch = matcher.find();
if (isMatch) {
backUrl = client.encrypt(backUrl);
}
if (!StringUtil.isEmpty(backUrl)) {
param.put("backUrl", backUrl);
}
param.put("source", 1L);
return concatUrlParams(method, param);
}
/**
* 通联支付 账户协议签约查询
*
* @param bizUserId 商户系统用户标识
* @return
*/
public OpenResponse signContractQuery(String bizUserId) {
String method = "allinpay.yunst.memberService.signContractQuery";
BizParameter param = new BizParameter();
OpenResponse response = getMemberInfo(bizUserId);
if (response != null) {
if ("OK".equals(response.getSubCode())) {
JSONObject data = JSON.parseObject(response.getData());
JSONObject infoObject = data.getJSONObject("memberInfo");
String name = infoObject.getString("name");
param.put("signAcctName", name);
}
}
param.put("bizUserId", bizUserId);
param.put("source", 1L);
return returnClient(method, param);
}
/**
* ---------------------------------------- 会员接口 结束 -----------------------------------------------
*/
/**
* ---------------------------------------- 订单(支付)接口 开始 -----------------------------------------------
*/
/**
* 通联支付 消费申请 微信小程序支付(收银宝)
*
* @param params 消费申请表单类
* @return
*/
public OpenResponse consumeApplyWechatPay(ConsumeApplyParams params) {
String method = "allinpay.yunst.orderService.consumeApply";
// 微信小程序支付(收银宝)
final HashMap<String, Object> WECHATPAYMINIPROGRAM = new HashMap<>();
WECHATPAYMINIPROGRAM.put("limitPay", "no_credit");
WECHATPAYMINIPROGRAM.put("subAppid", "1581648210684");
WECHATPAYMINIPROGRAM.put("amount", Long.parseLong(params.getAmount()));
WECHATPAYMINIPROGRAM.put("acct", "oC1vA5A8yqghB_6fN7qlan6JILio");
// 组装支付方式
final HashMap<String, Object> payMethod = new HashMap<>();
payMethod.put("WECHATPAY_MINIPROGRAM", WECHATPAYMINIPROGRAM);
BizParameter param = new BizParameter();
param.put("payerId", params.getPayerId());
param.put("recieverId", params.getRecieverId());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("amount", Long.parseLong(params.getAmount()));
param.put("fee", Long.parseLong(params.getFee()));
param.put("backUrl", params.getBackUrl());
param.put("payMethod", payMethod);
param.put("industryCode", params.getIndustryCode());
param.put("industryName", params.getIndustryName());
param.put("source", params.getSource());
param.put("validateType", params.getValidateType());
param.put("splitRule", params.getSplitRule());
param.put("frontUrl", params.getFrontUrl());
param.put("orderExpireDatetime", params.getOrderExpireDatetime());
param.put("goodsType", params.getGoodsType());
param.put("bizGoodsNo", params.getBizGoodsNo());
param.put("goodsName", params.getGoodsName());
param.put("goodsDesc", params.getGoodsDesc());
param.put("summary", params.getSummary());
param.put("extendInfo", params.getExtendInfo());
return returnClient(method, param);
}
/**
* 通联支付 消费申请 微信扫码支付(正扫)——收银宝
*
* @param params 消费申请表单类
* @return
*/
public OpenResponse consumeApplyScanWeiXin(ConsumeApplyParams params) {
String method = "allinpay.yunst.orderService.consumeApply";
// 微信扫码支付(正扫)——收银宝
final HashMap<String, Object> SCANWEIXIN = new HashMap<>();
SCANWEIXIN.put("limitPay", "no_credit");
SCANWEIXIN.put("amount", Long.parseLong(params.getAmount()));
// 组装支付方式
final HashMap<String, Object> payMethod = new HashMap<>();
payMethod.put("SCAN_WEIXIN", SCANWEIXIN);
BizParameter param = new BizParameter();
param.put("payerId", params.getPayerId());
param.put("recieverId", params.getRecieverId());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("amount", Long.parseLong(params.getAmount()));
param.put("fee", Long.parseLong(params.getFee()));
param.put("backUrl", params.getBackUrl());
param.put("payMethod", payMethod);
param.put("industryCode", params.getIndustryCode());
param.put("industryName", params.getIndustryName());
param.put("source", params.getSource());
param.put("validateType", params.getValidateType());
param.put("splitRule", params.getSplitRule());
param.put("frontUrl", params.getFrontUrl());
param.put("orderExpireDatetime", params.getOrderExpireDatetime());
param.put("goodsType", params.getGoodsType());
param.put("bizGoodsNo", params.getBizGoodsNo());
param.put("goodsName", params.getGoodsName());
param.put("goodsDesc", params.getGoodsDesc());
param.put("summary", params.getSummary());
param.put("extendInfo", params.getExtendInfo());
return returnClient(method, param);
}
/**
* 通联支付 托管代收申请(标准版 ) 微信小程序支付(收银宝)(用)
*
* @param params 托管代收申请表单类
* @return
*/
public OpenResponse agentCollectApplyWechatPay(AgentCollectApplyParams params) {
String method = "allinpay.yunst.orderService.agentCollectApply";
// 微信小程序支付(收银宝)
final HashMap<String, Object> WECHATPAYMINIPROGRAM = new HashMap<>();
WECHATPAYMINIPROGRAM.put("limitPay", "no_credit");
Double amount = Double.valueOf(params.getAmount());
WECHATPAYMINIPROGRAM.put("amount", Math.round(amount));
WECHATPAYMINIPROGRAM.put("acct", params.getAcct());
// 组装支付方式
final HashMap<String, Object> payMethod = new HashMap<>();
payMethod.put("WECHATPAY_MINIPROGRAM", WECHATPAYMINIPROGRAM);
BizParameter param = new BizParameter();
param.put("payerId", params.getPayerId());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("recieverList", params.getRecieverList());
param.put("tradeCode", params.getTradeCode());
param.put("amount", params.getAmount());
param.put("fee", params.getFee());
param.put("validateType", params.getValidateType());
param.put("frontUrl", params.getFrontUrl());
param.put("backUrl", params.getBackUrl());
param.put("orderExpireDatetime", params.getOrderExpireDatetime());
param.put("payMethod", payMethod);
param.put("goodsName", params.getGoodsName());
param.put("goodsDesc", params.getGoodsDesc());
param.put("industryCode", params.getIndustryCode());
param.put("industryName", params.getIndustryName());
param.put("source", params.getSource());
param.put("summary", params.getSummary());
param.put("extendInfo", params.getExtendInfo());
return returnClient(method, param);
}
/**
* 通联支付 托管代收申请(标准版 ) 微信扫码支付(正扫)——收银宝
*
* @param params 托管代收申请表单类
* @return
*/
public OpenResponse agentCollectApplyScanWeiXin(AgentCollectApplyParams params) {
String method = "allinpay.yunst.orderService.agentCollectApply";
// 微信扫码支付(正扫)——收银宝
final HashMap<String, Object> SCANWEIXIN = new HashMap<>();
SCANWEIXIN.put("limitPay", "no_credit");
SCANWEIXIN.put("amount", params.getAmount());
// 组装支付方式
final HashMap<String, Object> payMethod = new HashMap<>();
payMethod.put("SCAN_WEIXIN", SCANWEIXIN);
BizParameter param = new BizParameter();
// 收款列表
JSONArray receiverList = new JSONArray();
HashMap<String, Object> receiver1 = new HashMap<>();
receiver1.put("bizUserId", "bjlgsc6370");
receiver1.put("amount", 10L);
receiverList.add(new JSONObject(receiver1));
param.put("payerId", params.getPayerId());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("recieverList", receiverList);
param.put("tradeCode", params.getTradeCode());
param.put("amount", params.getAmount());
param.put("fee", params.getFee());
param.put("validateType", params.getValidateType());
param.put("frontUrl", params.getFrontUrl());
param.put("backUrl", params.getBackUrl());
param.put("orderExpireDatetime", params.getOrderExpireDatetime());
param.put("payMethod", payMethod);
param.put("goodsName", params.getGoodsName());
param.put("goodsDesc", params.getGoodsDesc());
param.put("industryCode", params.getIndustryCode());
param.put("industryName", params.getIndustryName());
param.put("source", params.getSource());
param.put("summary", params.getSummary());
param.put("extendInfo", params.getExtendInfo());
return returnClient(method, param);
}
/**
* 通联支付 托管代收申请(标准版 ) 收银宝网关支付
*
* @param params 托管代收申请表单类
* @return
*/
public OpenResponse agentCollectApplyGateWay(AgentCollectApplyGateWayParams params) {
String method = "allinpay.yunst.orderService.agentCollectApply";
// 收银宝网关支付
HashMap<String, Object> GATEWAY = new HashMap<>();
Double amount = Double.valueOf(params.getAmount()) * 100;
GATEWAY.put("amount", Math.round(amount));
GATEWAY.put("paytype", "B2B");
// 组装支付方式
HashMap<String, Object> payMethod = new HashMap<>();
payMethod.put("GATEWAY_VSP", GATEWAY);
BizParameter param = new BizParameter();
param.put("payerId", params.getPayerId());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("recieverList", params.getRecieverList());
param.put("tradeCode", params.getTradeCode());
param.put("amount", Math.round(amount));
Double fee = Double.valueOf(params.getFee()) * 100;
param.put("fee", Math.round(fee));
param.put("validateType", params.getValidateType());
param.put("frontUrl", params.getFrontUrl());
param.put("backUrl", params.getBackUrl());
param.put("orderExpireDatetime", params.getOrderExpireDatetime());
param.put("payMethod", payMethod);
param.put("goodsName", params.getGoodsName());
param.put("goodsDesc", params.getGoodsDesc());
param.put("industryCode", params.getIndustryCode());
param.put("industryName", params.getIndustryName());
param.put("source", params.getSource());
param.put("summary", params.getSummary());
param.put("extendInfo", params.getExtendInfo());
return returnClient(method, param);
}
/**
* 通联支付 确认支付(前台+短信验证码确认)
*
* @param params 确认支付(前台+短信验证码确认) 表单类
* @return
*/
public String payBySMS(PayBySMSParams params) {
String method = "allinpay.yunst.orderService.payBySMS";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("consumerIp", params.getConsumerIp());
if (!StringUtil.isEmpty(params.getVerificationCode())){
param.put("verificationCode", params.getVerificationCode());
}
return concatUrlParams(method, param);
}
/**
* 通联支付 单笔托管代付(标准版)
*
* @param params 单笔托管代付表单类
* @return
*/
public OpenResponse signalAgentPay(SignalAgentPayParams params) {
String method = "allinpay.yunst.orderService.signalAgentPay";
Double amounts = Double.valueOf(params.getAmount()) * 100;
Long amount = Math.round(amounts);
Double fees = Double.valueOf(params.getFee()) * 100;
Long fee = Math.round(fees);
JSONArray collectPayList = new JSONArray();
HashMap<String, Object> collect1 = new HashMap<>();
collect1.put("bizOrderNo", params.getBizOrderNo());
collect1.put("amount", (amount - fee));
collect1.put("orderNo", params.getOrderNo());
collectPayList.add(new JSONObject(collect1));
BizParameter param = new BizParameter();
param.put("bizOrderNo", params.getNewBizOrderNo());
param.put("collectPayList", collectPayList);
param.put("accountSetNo", config.getNumber());
param.put("bizUserId", params.getBizUserId());
param.put("tradeCode", params.getTradeCode());
param.put("amount", (amount - fee));
param.put("fee", 0L);
param.put("backUrl", params.getBackUrl());
param.put("summary", params.getSummary());
param.put("extendInfo", params.getExtendInfo());
return returnClient(method, param);
}
/**
* 通联支付 退款申请
*
* @param params 退款申请表单类
* @return
*/
public OpenResponse refund(RefundParams params) {
String method = "allinpay.yunst.orderService.refund";
BizParameter param = new BizParameter();
param.put("oriBizOrderNo", params.getOriBizOrderNo());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("bizUserId", params.getBizUserId());
param.put("amount", params.getAmount());
if (!StringUtil.isEmpty(params.getOriOrderNo())) {
param.put("oriOrderNo", params.getOriOrderNo());
}
if (!StringUtil.isEmpty(params.getRefundType())) {
param.put("refundType", params.getRefundType());
}
if (!StringUtil.isEmpty(params.getRefundList())) {
param.put("refundList", params.getRefundList());
}
if (!StringUtil.isEmpty(params.getBackUrl())) {
param.put("backUrl", params.getBackUrl());
}
if (!StringUtil.isEmpty(params.getCouponAmount())) {
param.put("couponAmount", params.getCouponAmount());
}
if (!StringUtil.isEmpty(params.getFeeAmount())) {
param.put("feeAmount", params.getFeeAmount());
}
if (!StringUtil.isEmpty(params.getRefundAccount())) {
param.put("refundAccount", params.getRefundAccount());
}
if (!StringUtil.isEmpty(params.getBenefitdetail())) {
param.put("benefitdetail", params.getBenefitdetail());
}
if (!StringUtil.isEmpty(params.getExtendInfo())) {
param.put("extendInfo", params.getExtendInfo());
}
return returnClient(method, param);
}
/**
* 通联支付 提现申请
*
* @param params 提现申请表单类
* @return
*/
public OpenResponse withdrawApply(WithdrawApplyParams params) {
OpenClient client = configClient();
String method = "allinpay.yunst.orderService.withdrawApply";
BizParameter param = new BizParameter();
param.put("bizOrderNo", params.getBizOrderNo());
param.put("bizUserId", params.getBizUserId());
param.put("accountSetNo", config.getNumber());
Double amounts = Double.valueOf(params.getAmount()) * 100;
Long amount = Math.round(amounts);
param.put("amount", amount);
param.put("fee", params.getFee());
param.put("backUrl", params.getBackUrl());
param.put("bankCardNo", client.encrypt(params.getBankCardNo()));
param.put("industryCode", params.getIndustryCode());
param.put("industryName", params.getIndustryName());
param.put("source", params.getSource());
if (!StringUtil.isEmpty(params.getValidateType())) {
param.put("validateType", params.getValidateType());
}
if (!StringUtil.isEmpty(params.getOrderExpireDatetime())) {
param.put("orderExpireDatetime", params.getOrderExpireDatetime());
}
if (!StringUtil.isEmpty(params.getBankCardPro())) {
param.put("bankCardPro", params.getBankCardPro());
}
if (!StringUtil.isEmpty(params.getWithdrawType())) {
param.put("withdrawType", params.getWithdrawType());
}
if (!StringUtil.isEmpty(params.getSummary())) {
param.put("summary", params.getSummary());
}
if (!StringUtil.isEmpty(params.getExtendInfo())) {
param.put("extendInfo", params.getExtendInfo());
}
return returnClient(method, param);
}
/**
* 通联支付 订单状态查询
*
* @param orderNo 云商通订单号
* @param bizOrderNo 商户订单号(支付订单)
* @return
*/
public OpenResponse getOrderStatus(String orderNo, String bizOrderNo) {
String method = "allinpay.yunst.orderService.getOrderStatus";
BizParameter param = new BizParameter();
if (!StringUtil.isEmpty(orderNo)) {
param.put("orderNo", orderNo);
}
param.put("bizOrderNo", bizOrderNo);
return returnClient(method, param);
}
/**
* 通联支付 平台转账(allinpay.yunst.orderService.applicationTransfer)
* 该接口一般用于平台向用户发红包、各类代金券、体验金、购物返利等营销活动。
*
* @param targetBizUserId 收款会员的BizUserId
* @param bizTransferNo 商户订单号(支付订单)
* @return
*/
public OpenResponse applicationTransfer(String targetBizUserId, String amountStr, String bizTransferNo) {
String method = "allinpay.yunst.orderService.applicationTransfer";
BizParameter param = new BizParameter();
param.put("targetBizUserId", targetBizUserId);
param.put("bizTransferNo", bizTransferNo);
param.put("sourceAccountSetNo", "100001");
param.put("targetAccountSetNo", config.getNumber());
Double amounts = Double.valueOf(amountStr) * 100;
Long amount = Math.round(amounts);
param.put("amount", amount);
return returnClient(method, param);
}
/**
* 通联支付 订单状态查询
*
* @param bizOrderNo 商户订单号(支付订单)
* @return
*/
public OpenResponse getOrderDetail(String bizOrderNo) {
String method = "allinpay.yunst.orderService.getOrderDetail";
BizParameter param = new BizParameter();
param.put("bizOrderNo", bizOrderNo);
return returnClient(method, param);
}
/**
* 通联支付 查询余额
*
* @param bizUserId 商户系统用户标识
* @return
*/
public OpenResponse queryBalance(String bizUserId) {
String method = "allinpay.yunst.orderService.queryBalance";
BizParameter param = new BizParameter();
param.put("bizUserId", bizUserId);
param.put("accountSetNo", allinPayConfig.getNumber());
return returnClient(method, param);
}
/**
* 通联支付 查询账户收支明细接口
*
* @param params 查询账户收支明细表单
* @return
*/
public OpenResponse queryInExpDetail(QueryInExpDetailParams params) {
String method = "allinpay.yunst.orderService.queryInExpDetail";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("accountSetNo", params.getAccountSetNo());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("dateStart", params.getDateStart());
param.put("dateEnd", params.getDateEnd());
param.put("startPosition", params.getStartPosition());
param.put("queryNum", params.getQueryNum());
if (!StringUtil.isEmpty(params.getAccountSetNo())) {
param.put("accountSetNo", params.getAccountSetNo());
}
if (!StringUtil.isEmpty(params.getBizOrderNo())) {
param.put("bizOrderNo", params.getBizOrderNo());
}
if (!StringUtil.isEmpty(params.getTradeType())) {
param.put("tradeType", params.getTradeType());
}
return returnClient(method, param);
}
/**
* 通联支付 订单分账明细查询
*
* @param bizOrderNo 商户订单号(支付订单)
* @return
*/
public OpenResponse getOrderSplitRuleListDetail(String bizOrderNo) {
String method = "allinpay.yunst.orderService.getOrderSplitRuleListDetail";
BizParameter param = new BizParameter();
param.put("bizOrderNo", bizOrderNo);
return returnClient(method, param);
}
/**
* 通联支付 订单关闭
*
* @param bizOrderNo 商户订单号(支付订单)
* @return
*/
public OpenResponse closeOrder(String bizOrderNo) {
String method = "allinpay.yunst.orderService.closeOrder";
BizParameter param = new BizParameter();
param.put("bizOrderNo", bizOrderNo);
return returnClient(method, param);
}
/**
* ---------------------------------------- 订单(支付)接口 结束 -----------------------------------------------
*/
}
二、流程
1、实体类
import cn.hutool.json.JSONArray;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* Desc: 通联支付 托管代收申请(标准版)-微信小程序支付(收银宝)
*
* @author enjoy[306911498@qq.com]
* @since 2023/8/9 16:06
*/
@Data
public class AgentCollectApplyParams {
@NotBlank(message = "付款方不能为空")
@Schema(description = "付款方 商户系统用户标识")
private String payerId;
@NotBlank(message = "商户订单号(支付订单)不能为空")
@Schema(description = "商户订单号(支付订单)")
private String bizOrderNo;
@Schema(description = "收款列表")
private JSONArray recieverList;
@NotBlank(message = "订单金额不能为空")
@Schema(description = "订单金额")
private String amount;
@NotBlank(message = "手续费不能为空")
@Schema(description = "手续费")
private String fee;
@NotBlank(message = "后台通知地址不能为空")
@Schema(description = "后台通知地址")
private String backUrl;
@NotBlank(message = "业务码不能为空")
@Schema(description = "业务码")
private String tradeCode;
@NotBlank(message = "支付平台用户标识不能为空")
@Schema(description = "支付平台用户标识")
private String acct;
//@NotBlank(message = "支付方式不能为空")
@Schema(description = "支付方式")
private JSONArray payMethod;
@NotBlank(message = "行业代码不能为空")
@Schema(description = "行业代码")
private String industryCode;
@NotBlank(message = "行业名称不能为空")
@Schema(description = "行业名称")
private String industryName;
@NotBlank(message = "访问终端类型不能为空")
@Schema(description = "访问终端类型")
private String source;
@Schema(description = "交易验证方式 无验证:0,短信验证码:1,支付密码:2")
private String validateType;
@Schema(description = "分账规则")
private JSONArray splitRule;
@Schema(description = "前台通知地址")
private String frontUrl;
@Schema(description = "订单过期时间")
private String orderExpireDatetime;
@Schema(description = "商品类型")
private String goodsType;
@Schema(description = "商户系统商品编号")
private String bizGoodsNo;
@Schema(description = "商品名称 微信原生APP支付必传")
private String goodsName;
@Schema(description = "商品描述")
private String goodsDesc;
@Schema(description = "摘要 不可包含“|”及换行符+,空格,/,?,%,#,&,=等特殊字符,最多50个字符")
private String summary;
@Schema(description = "扩展参数 不可包含“|”及换行符+,空格,/,?,%,#,&,=等特殊字符,最多100个字符")
private String extendInfo;
}
import cn.hutool.json.JSONArray;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* Desc: 通联支付 单笔托管代付(标准版)
*
* @author enjoy[306911498@qq.com]
* @since 2023/8/10 15:26
*/
@Data
public class SignalAgentPayParams {
@NotBlank(message = "商户订单号(支付订单)不能为空")
@Schema(description = "商户订单号(支付订单)")
private String NewBizOrderNo;
@NotBlank(message = "原商户订单号(支付订单)不能为空")
@Schema(description = "原商户订单号(支付订单)")
private String bizOrderNo;
@NotBlank(message = "相关代收订单“云商通订单号不能为空")
@Schema(description = "相关代收订单“云商通订单号")
private String orderNo;
@Schema(description = "源托管代收订单付款信息")
private JSONArray collectPayList;
@NotBlank(message = "收款账户不能为空")
@Schema(description = "收款账户 商户系统用户标识")
private String bizUserId;
// @NotBlank(message = "收款人的账户集编号不能为空")
@Schema(description = "收款人的账户集编号")
private String accountSetNo;
@NotBlank(message = "订单金额不能为空")
@Schema(description = "订单金额")
private String amount;
@NotBlank(message = "手续费不能为空")
@Schema(description = "手续费")
private String fee;
@NotBlank(message = "后台通知地址不能为空")
@Schema(description = "后台通知地址")
private String backUrl;
@NotBlank(message = "业务码不能为空")
@Schema(description = "业务码")
private String tradeCode;
@Schema(description = "分账规则")
private JSONArray splitRuleList;
@Schema(description = "商品类型")
private String goodsType;
@Schema(description = "商户系统商品编号")
private String bizGoodsNo;
@Schema(description = "摘要 不可包含“|”及换行符+,空格,/,?,%,#,&,=等特殊字符,最多50个字符")
private String summary;
@Schema(description = "扩展参数 不可包含“|”及换行符+,空格,/,?,%,#,&,=等特殊字符,最多100个字符")
private String extendInfo;
}
2、申请支付订单-托管代收申请
文档:通联支付-通商云开放平台
说明:这一步类似于你在淘宝下单后他不会立马支付,会进入一个倒计时的支付订单状态。付钱后不会直接给收款方,他会打给绑定这个通联的中间商。
代码:代码在[通联demo]可以找到,这里主要要要做分账
/**
* 通联支付 托管代收申请(标准版 ) 微信小程序支付(收银宝)(用)
*
* @param params 托管代收申请表单类
* @return
*/
public OpenResponse agentCollectApplyWechatPay(AgentCollectApplyParams params) {
String method = "allinpay.yunst.orderService.agentCollectApply";
// 微信小程序支付(收银宝)
final HashMap<String, Object> WECHATPAYMINIPROGRAM = new HashMap<>();
WECHATPAYMINIPROGRAM.put("limitPay", "no_credit");
Double amount = Double.valueOf(params.getAmount());
WECHATPAYMINIPROGRAM.put("amount", Math.round(amount));
WECHATPAYMINIPROGRAM.put("acct", params.getAcct());
// 组装支付方式
final HashMap<String, Object> payMethod = new HashMap<>();
payMethod.put("WECHATPAY_MINIPROGRAM", WECHATPAYMINIPROGRAM);
BizParameter param = new BizParameter();
param.put("payerId", params.getPayerId());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("recieverList", params.getRecieverList());
param.put("tradeCode", params.getTradeCode());
param.put("amount", params.getAmount());
param.put("fee", params.getFee());
param.put("validateType", params.getValidateType());
param.put("frontUrl", params.getFrontUrl());
param.put("backUrl", params.getBackUrl());
param.put("orderExpireDatetime", params.getOrderExpireDatetime());
param.put("payMethod", payMethod);
param.put("goodsName", params.getGoodsName());
param.put("goodsDesc", params.getGoodsDesc());
param.put("industryCode", params.getIndustryCode());
param.put("industryName", params.getIndustryName());
param.put("source", params.getSource());
param.put("summary", params.getSummary());
param.put("extendInfo", params.getExtendInfo());
return returnClient(method, param);
}
3、企业步骤 - 确认支付(前台+短信验证码确认)
文档:通联支付-通商云开放平台
说明:企业一般使用对公账号支付,这里返回一个支付路径,需要在pc上面支付
代码:
/**
* 通联支付 确认支付(前台+短信验证码确认)
*
* @param params 确认支付(前台+短信验证码确认) 表单类
* @return
*/
public String payBySMS(PayBySMSParams params) {
String method = "allinpay.yunst.orderService.payBySMS";
BizParameter param = new BizParameter();
param.put("bizUserId", params.getBizUserId());
param.put("bizOrderNo", params.getBizOrderNo());
param.put("consumerIp", params.getConsumerIp());
if (!StringUtil.isEmpty(params.getVerificationCode())){
param.put("verificationCode", params.getVerificationCode());
}
return concatUrlParams(method, param);
}
4、支付成功回调
代码:
// 将request中的参数转换成Map
public static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
Map<String, String> retMap = new HashMap<String, String>();
Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
for (Map.Entry<String, String[]> entry : entrySet) {
String name = entry.getKey();
String[] values = entry.getValue();
int valLen = values.length;
if (valLen == 1) {
retMap.put(name, values[0]);
} else if (valLen > 1) {
StringBuilder sb = new StringBuilder();
for (String val : values) {
sb.append(",").append(val);
}
retMap.put(name, sb.toString().substring(1));
} else {
retMap.put(name, "");
}
}
return retMap;
}
/**
* 订单支付完成后回调接口
*/
@ResponseBody
@RequestMapping("/..Back")
public void PayCallBack(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> paramsMap = convertRequestParamsToMap(request);
// 根据具体业务处理
.....
}
5、收款方确认收款-单笔托管代付
文档:通联支付-通商云开放平台
说明:这里可以看作中间商把钱付给收款方
代码
/**
* 通联支付 单笔托管代付(标准版)
*
* @param params 单笔托管代付表单类
* @return
*/
public OpenResponse signalAgentPay(SignalAgentPayParams params) {
String method = "allinpay.yunst.orderService.signalAgentPay";
Double amounts = Double.valueOf(params.getAmount()) * 100;
Long amount = Math.round(amounts);
Double fees = Double.valueOf(params.getFee()) * 100;
Long fee = Math.round(fees);
JSONArray collectPayList = new JSONArray();
HashMap<String, Object> collect1 = new HashMap<>();
collect1.put("bizOrderNo", params.getBizOrderNo());
collect1.put("amount", (amount - fee));
collect1.put("orderNo", params.getOrderNo());
collectPayList.add(new JSONObject(collect1));
BizParameter param = new BizParameter();
param.put("bizOrderNo", params.getNewBizOrderNo());
param.put("collectPayList", collectPayList);
param.put("accountSetNo", config.getNumber());
param.put("bizUserId", params.getBizUserId());
param.put("tradeCode", params.getTradeCode());
param.put("amount", (amount - fee));
param.put("fee", 0L);
param.put("backUrl", params.getBackUrl());
param.put("summary", params.getSummary());
param.put("extendInfo", params.getExtendInfo());
return returnClient(method, param);
}
6、确认收款回调
说明:回调成功后走钱才会到收款方手里。
代码
/**
* 确认收款后回调 单笔托管代付回调通知
*
* @param request
* @param response
* @throws IOException
* @throws GeneralSecurityException
*/
@ResponseBody
@RequestMapping({"/payNotify"})
public void payNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, GeneralSecurityException {
Map<String, String> paramsMap = StringUtilXu.convertRequestParamsToMap(request);
// 具体业务实现
......
}
三、总结
流程不是很复杂,就是有点绕,而且企业支付和普通的支付多了一步。
这里主要测试是针对微信支付,其他的支付方式也差不多,改一下参数就行。
分账的时候有点麻烦,平台要提成几个点,这里要注意计算方式。
通联有很多id,注意使用的时候不要冲突,有一些是你传给你他的。
最后祝大家一遍过!