2025-04-08回来更新:
支付宝如果设置成调用第三方支付,记住,是 无法通过进入小程序后台进行 提审的,要么解绑后提审,然后重新绑定,但是里面的token也会改变,要换成最新的;或者调用接口来提审
AlipayOpenMiniVersionAuditApplyRequest
支付宝真的好麻烦,唉😔
做了一个停车收费的小程序,要实现将支付金额转账到对应商户的账户中,比如小区A的人使用小程序支付到商户A的账号上,小区B的人使用小程序支付到商户B的账号上
微信
微信倒是容易,多申请几个商户,生成 证书、密钥等内容,然后关联对应的小程序,调用接口发起支付的时候,传入对应商户的各项参数即可
/**
* fee单位为分,支付需要乘以100
* 因为微信支付涉及多商户,mchId、key参数为对应商户的内容
*
* @param openid
* @param fee
* @return
* @throws Exception
*/
public String wxpay(String openid,int fee,String mchId,String key) throws Exception {
fee = fee * 100;
Map<String,String> map = new HashMap<>();
String randomstr = generateNonceStr(); // 随机字符串
String out_trade_no = GetRandom.getRandomStringByLength(32);
map.put("appid",WeChatService.miniProgramAppId);// 小程序appid
map.put("mch_id",mchId);// 商户号
map.put("sign_type","MD5"); // 加密方式
map.put("nonce_str",randomstr);// 随机字符串
map.put("body","停车收费");// 商品编号
map.put("notify_url","xxx"); // 回调地址
map.put("out_trade_no", out_trade_no);// 订单号
map.put("spbill_create_ip","xx.xx.xx");// 终端ip(调用微信支付API的机器IP)
map.put("total_fee",fee+"");// 订单金额
map.put("trade_type","JSAPI"); // 交易类型交易类型
map.put("openid",openid);// openid
String orderstr = GroupWeuxin.formatUrlMap(map,false,false); //生成签名 将集合M内非空参数值的参数按照参数名ASCII码从小到大排序
String SignTemp = orderstr+"&key="+key; // 拼接商户key
// String SignTemp = orderstr+"&key="+WeChatService.key; // 拼接商户key
String sign = Md5Util.getMD5String(SignTemp).toUpperCase();// MD5加密 并且转换为大写 获得签名
map.put("sign",sign);
String xml = mapToXml(map);
String xmlstr = new String(xml.getBytes("UTF-8"), "UTF-8");
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";// 调用统一下单接口
String list=sendPost(url,xmlstr);
Map map1 = WXPayUtil.xmlToMap(list);
String prepay_id = (String)map1.get("prepay_id");
Map<String,String> map2 = new HashMap<>();
map2.put("appId",WeChatService.miniProgramAppId);//appId注意大小写
map2.put("timeStamp",String.valueOf(WXPayUtil.getCurrentTimestamp())); // 时间戳微信Util中有
map2.put("nonceStr",randomstr);// 随机字符串
map2.put("package","prepay_id="+prepay_id);// 这里千万千万注意格式
map2.put("signType","MD5");// 签名方式
String paixu2 = GroupWeuxin.formatUrlMap(map2,false,false); //生成签名 将集合内非空参数值的参数按照参数名ASCII码从小到大排序
String SignTemp2 = paixu2+"&key="+key; // 拼接key MD5加密 并且转换为大写
// String SignTemp2 = paixu2+"&key="+WeChatService.key; // 拼接key MD5加密 并且转换为大写
String sign2 = Md5Util.getMD5String(SignTemp2).toUpperCase();
map2.put("paySign",sign2);
map2.put("outTradeNo",out_trade_no);// 订单号
System.out.println(map2);
return JSON.toJSONString(map2);
}
支付宝
这个比较困难 ,不像微信一样调用接口的时候传入对应商户的参数就行,还需要通过创建第三方应用、关联第三方应用才能实现支付,参考这个文档 小程序文档 - 支付宝文档中心
首先,我作为开发者,已经在商户A中,上线了一个小程序,然后就是注册使用小程序的商户,假设称为商户B 商户注册
1、申请商户B完成后,开通商户B的JSAPI,然后关联上小程序
ps:商户A如果为了提审而解绑了小程序,提审完成后,这里也要关联上的
2、然后在商户A中,创建第三方应用 第三方应用 - 支付宝开放平台
创建成功之后进行第三方应用公钥、密钥、加签方式、白名单等属性的配置
3、这两个都配置完成后,第三方提交审核
4、第三方审核通过后,邀请商户B授权
这里演示用的是单个授权
5、登录商户B,在消息--待办任务进行确认通过授权
6、选择要授权的应用,通过
7、还有些步骤可能没说,但大致差不多就这样子,然后再就将商户A也邀请过来
8、第三方应用接入JSAPI
9、看到两个商户都在第三方应用中,准备工作就差不多了,注意:这里授权token就是 下面代码中要传入 的第三方授权应用中的app_auth_token!!!
10、最后是代码部分,获取支付宝openid,注意:!部分的参数不要弄错,千万注意!!!
// 获取支付宝小程序中的openid!!!
public static Map<String, Object> getUserId(String authCode){
Map<String, Object> map = new HashMap<>();
// 配置支付宝客户端,注意!这里都要用商户A小程序的参数!!!
AlipayClient alipayClient = new DefaultAlipayClient(
server_url,
appid,
private_key,
"json",
"UTF-8",
alipay_public_key,
sign_type
);
try {
// 1. 换取访问令牌
AlipaySystemOauthTokenRequest tokenRequest = new AlipaySystemOauthTokenRequest();
tokenRequest.setGrantType("authorization_code");
tokenRequest.setCode(authCode);
// 2. 执行请求
AlipaySystemOauthTokenResponse tokenResponse = alipayClient.execute(tokenRequest);
// 3. 直接获取 user_id(auth_user 场景需确认是否返回)
if (tokenResponse.isSuccess()) {
map.put("msg", tokenResponse);
map.put("openid", tokenResponse.getOpenId());
map.put("code", 200);
return map; // 部分情况下直接返回 user_id:ml-citation{ref="3,4" data="citationList"}
}else {
System.out.println(JSON.toJSONString(tokenResponse));
}
}catch (Exception e){
e.printStackTrace();
map.put("msg", e.getMessage());
map.put("code", 505);
}
return map;
}
/**
* 生成支付订单
* @param totalAmount
* @param userId 这里传入的其实是openid!!!
* @return
*/
public static Map<String,Object> tradeCreate(String totalAmount, String userId) {
// 配置支付宝客户端,注意!这里client的创建都要用第三方的!!!
AlipayClient alipayClient = new DefaultAlipayClient(
server_url,
appid,
private_key,
"json",
"UTF-8",
alipay_public_key,
sign_type
);
Map<String,Object> map = new HashMap();
// 构造请求参数以调用接口
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
AlipayTradeCreateModel model = new AlipayTradeCreateModel();
// 设置商户订单号
String outTradeNo = "tradeCreate" + System.currentTimeMillis() + (long) (Math.random() * 10000000L);
System.out.println("商户订单号:"+outTradeNo);
model.setOutTradeNo(outTradeNo);
// 设置订单总金额-单位是元,和微信不一样
model.setTotalAmount(totalAmount);
// 设置订单标题
model.setSubject("IJ");
// 设置产品码
model.setProductCode("JSAPI_PAY");
// 设置小程序支付中
model.setOpAppId("商户A小程序的APPID!!");
// 设置订单附加信息
model.setBody("缴费金额:"+totalAmount+"元");
// 设置买家支付宝用户唯一标识
model.setOpBuyerOpenId(userId);
request.setBizModel(model);
request.putOtherTextParam("app_auth_token", "第三方应用中对应商户的token!");
try {
AlipayTradeCreateResponse response = alipayClient.execute(request);
System.out.println(JSON.toJSONString(response));
if (response.isSuccess()) {
String tradeNo = response.getTradeNo(); // 支付宝交易号:ml-citation{ref="2" data="citationList"}
System.out.println("订单创建成功,交易号:" + tradeNo);
map.put("msg", response);
map.put("tradeNo", tradeNo);
map.put("code", 200);
aliPayQuery(outTradeNo);
} else {
System.err.println("错误码:" + response.getCode() + ",错误信息:" + response.getMsg());
map.put("msg", response.getMsg());
map.put("code", response.getCode());
// sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
System.out.println(diagnosisUrl);
}
} catch (AlipayApiException e) {
map.put("msg", e.getMessage());
map.put("code", 505);
e.printStackTrace();
}
return map;
}
因为还有其他的任务,支付宝多商户支付这块内容我断断续续花了快一周的时间,就是因为里面的几个参数没有写对,所以这里特别做记录,希望后来者注意