实战:第八章:支付宝Native,JSAPI支付与微信Native,JSAPI,MWEB支付实现

最后

很多程序员,整天沉浸在业务代码的 CRUD 中,业务中没有大量数据做并发,缺少实战经验,对并发仅仅停留在了解,做不到精通,所以总是与大厂擦肩而过。

我把私藏的这套并发体系的笔记和思维脑图分享出来,理论知识与项目实战的结合,我觉得只要你肯花时间用心学完这些,一定可以快速掌握并发编程。

不管是查缺补漏还是深度学习都能有非常不错的成效,需要的话记得帮忙点个赞支持一下

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

/**

  • 微信H5支付,非微信浏览器

  • @return

*/

@Bean

public WxPayH5MWEB getWxPayH5MWEB(){

WxPayH5MWEB wxPayH5Bean = new WxPayH5MWEB();

Map<String, String> map = new HashMap<>();

map.put(“wx_h5_appid”, wx_h5_appid);

map.put(“wx_h5_appsecret”, wx_h5_appsecret);

map.put(“wx_h5_partnerkey”, wx_h5_partnerkey);

map.put(“wx_h5_mch_id”, wx_h5_mch_id);

map.put(“wx_mweb_notify_url”, wx_mweb_notify_url);

map.put(“wx_mweb_return_url_h5”,wx_mweb_return_url_h5);

wxPayH5Bean.setPayMap(map);

return wxPayH5Bean;

}

/**

  • 支付宝H5支付,非微信浏览器,微信不允许调用支付宝的支付接口

  • @return

*/

@Bean

public AliPayH5Bean getAlipayH5Info(){

AliPayH5Bean payBean = new AliPayH5Bean();

Map<String, String> map = new HashMap<>();

map.put(“alipay_app_id”, alipay_h5_app_id);

map.put(“alipay_private_key”, alipay_h5_private_key);

map.put(“alipay_public_key”, alipay_h5_public_key);

map.put(“notify_url”, alipay_h5_notify_url);

map.put(“return_url”, aplipay_h5_return_url);

map.put(“is_real_pay”, is_real_pay);

payBean.setPayMap(map);

return payBean;

}

}

然后看看自定义实体类:

public class AliPayH5Bean {

private Map payMap;

public Map getPayMap() {

return payMap;

}

public void setPayMap(Map payMap) {

this.payMap = payMap;

}

}

public class WxPayH5MWEB {

private Map payMap;

public Map getPayMap() {

return payMap;

}

public void setPayMap(Map payMap) {

this.payMap = payMap;

}

}

public class WxPayH5JSAPI {

private Map payMap;

public Map getPayMap() {

return payMap;

}

public void setPayMap(Map payMap) {

this.payMap = payMap;

}

}

然后是pc扫码的支付:

@Autowired

WxClient wxClient;

@LoginRequired(isNeedLogin = true)

@ApiOperation(“pc端去支付,支付主接口,用于控制整体支付流程”)

@RequestMapping(value = “/alipay/submit”, method = RequestMethod.GET)

@ResponseBody

public String goToPay(String orderSn, BigDecimal totalAmount, Integer channelId) {

//根据订单创建支付信息并保存,这里真实开发不会使用金额传参,容易被篡改价格,但是为了方便暂时先这样写

Map<String, String> requestMap = savePayInfo(orderSn, totalAmount);

String form=“”;

if(PayConstant.CHANNELALINATIVE.equals(channelId)){

//阿里支付

form = generateForm(requestMap, form);

}else if (PayConstant.CHANNELWXNATIVE.equals(channelId)){

//微信支付

Map map = wxClient.getMap();

map.put(“out_trade_no”,orderSn);

map.put(“total_fee”,totalAmount);

String code_url = PayUtils.wxPcPay(map);

String fileName = TimeUtils.getCurrentTime(“yyyyMMddHHmmss”) + “.png”;

String img_path = String.valueOf(map.get(“img_path”));

//说明:商户后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url,

// 商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。

// 注意:code_url有效期为2小时,过期后扫码不能再发起支付。

//将code_url的值生成二维码图片上传到七牛云,这里就不写上传七牛云的代码了,

// img_path:保存二维码的基础全路径+“/qrcode/”+fileName:保存二维码的图片名称+code_url:保存到二维码里的内容

form = img_path + “/qrcode/” + fileName;

}else{

//其他第三方支付(未接入)

}

//发送检查支付结果的消息队列(这里只检查了阿里的支付)

payService.sendingPayMQ(orderSn,6,channelId);

return form;

}

/**

  • 支付宝pc端扫码支付没有写到工具类里面了,支付宝生成表单

  • @param requestMap

  • @param form

  • @return

*/

private String generateForm(Map<String, String> requestMap, String form) {

//创建PC场景下单并支付请求对象

AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request

//设置同步返回地址,HTTP/HTTPS开头字符串

alipayRequest.setReturnUrl(PCPayConfig.alipay_pc_return_url);

//支付宝服务器主动通知商户服务器里指定的页面http/https路径。

alipayRequest.setNotifyUrl(PCPayConfig.alipay_pc_notify_url);//在公共参数中设置回跳和通知地址

//填充业务参数

alipayRequest.setBizContent(JSON.toJSONString(requestMap));

try {

//调用SDK生成表单

form = alipayClient.pageExecute(alipayRequest).getBody();

} catch (AlipayApiException e) {

e.printStackTrace();

}

return form;

}

看看自定义的实体类:

public class WxClient {

private Map map;

public Map getMap() {

return map;

}

public void setMap(Map map) {

this.map = map;

}

}

然后看看pc的配置类:

import com.alipay.api.AlipayClient;

import com.alipay.api.DefaultAlipayClient;

import com.javaliao.portal.bean.WxClient;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.PropertySource;

import java.util.HashMap;

import java.util.Map;

@Configuration

@PropertySource(“classpath:PCPay.properties”)

public class PCPayConfig {

//阿里pc端

@Value(“${alipay_pc_url}”)

private String alipay_pc_url;

@Value(“${alipay_pc_public_key}”)

public static String alipay_pc_public_key;

@Value(“${alipay_pc_private_key}”)

private String alipay_pc_private_key;

@Value(“${alipay_pc_app_id}”)

private String alipay_pc_app_id;

@Value(“${alipay_pc_notify_url}”)

public static String alipay_pc_notify_url;

@Value(“${alipay_pc_return_url}”)

public static String alipay_pc_return_url;

//微信pc端

@Value(“${wx_pc_appid}”)

public static String wx_pc_appid;

@Value(“${wx_pc_url}”)

public static String wx_pc_url;

@Value(“${wx_pc_appsecret}”)

public static String wx_pc_appsecret;

@Value(“${wx_pc_partnerkey}”)

public static String wx_pc_partnerkey;

@Value(“${wx_pc_mch_id}”)

public static String wx_pc_mch_id;

@Value(“${wx_pc_notify_url}”)

public static String wx_pc_notify_url;

@Value(“${img_path}”)

public static String img_path;

public final static String format=“json”;

public final static String charset=“utf-8”;

public final static String sign_type=“RSA2”;

@Bean

public WxClient wxClient(){

WxClient wxClient = new WxClient();

Map<String , Object> map = new HashMap<>();

map.put(“wx_pc_appid”,wx_pc_appid);

map.put(“wx_pc_appsecret”,wx_pc_appsecret);

map.put(“wx_pc_partnerkey”,wx_pc_partnerkey);

map.put(“wx_pc_mch_id”,wx_pc_mch_id);

map.put(“wx_pc_notify_url”,wx_pc_notify_url);

map.put(“wx_pc_url”,wx_pc_url);

map.put(“img_path”,img_path);

wxClient.setMap(map);

return wxClient;

}

/**

  • pc端支付宝支付Native

  • @return

*/

@Bean

public AlipayClient alipayClient(){

return new DefaultAlipayClient(alipay_pc_url,alipay_pc_app_id,alipay_pc_private_key,format,charset,alipay_pc_public_key,sign_type);

}

}

支付的工具类:

package com.javaliao.portal.util;

import com.alibaba.fastjson.JSON;

import com.alipay.api.AlipayApiException;

import com.alipay.api.AlipayClient;

import com.alipay.api.DefaultAlipayClient;

import com.alipay.api.domain.AlipayTradeAppPayModel;

import com.alipay.api.domain.AlipayTradeWapPayModel;

import com.alipay.api.internal.util.AlipaySignature;

import com.alipay.api.request.*;

import com.alipay.api.response.AlipayTradeAppPayResponse;

import com.alipay.api.response.AlipayTradeRefundResponse;

import com.javaliao.portal.bean.WXPubBean;

import com.javaliao.portal.log4j.BaseLogger;

import org.apache.http.HttpResponse;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;

import org.apache.http.conn.ssl.SSLContexts;

import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.util.EntityUtils;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import javax.net.ssl.SSLContext;

import javax.xml.parsers.DocumentBuilder;

import java.io.ByteArrayInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import java.net.URLEncoder;

import java.security.KeyStore;

import java.util.HashMap;

import java.util.Map;

import java.util.SortedMap;

import java.util.TreeMap;

public class PayUtils {

/**

  • 支付宝H5支付

  • @param map

  • @return

*/

public static String alipayh5(Map<String, Object> map) {

AlipayClient alipayClient = new DefaultAlipayClient(“https://openapi.alipay.com/gateway.do”,map.get(“alipay_app_id”).toString(), map.get(“alipay_private_key”).toString(), “json”, “utf-8”, map.get(“alipay_public_key”).toString(),“RSA2”);

AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();

model.setOutTradeNo(map.get(“out_trade_no”).toString());

model.setSubject(“委托检测服务”);

model.setTotalAmount(map.get(“total_fee”).toString());

model.setBody(“委托检测服务”);

model.setTimeoutExpress(“2m”);

model.setProductCode(“FAST_INSTANT_TRADE_PAY”);

// 创建手机网站API对应的request:AlipayTradeWapPayRequest;pc端的是AlipayTradePagePayRequest

AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();

alipayRequest.setReturnUrl(map.get(“return_url”).toString());

alipayRequest.setNotifyUrl(map.get(“notify_url”).toString());

alipayRequest.setBizModel(model);

// 调用SDK生成表单

String form = null;

try {

form = alipayClient.pageExecute(alipayRequest).getBody();

BaseLogger.info("支付宝支付生成同步响应报文: " + form);

/*直接将完整的表单html输出到页面。说明:手机网站支付alipay.trade.wap.pay:

对于页面跳转类API,SDK不会也无法像系统调用类API一样自动请求支付宝并获得结果,

而是在接受request请求对象后,为开发者生成前台页面请求需要的完整form表单的html(包含自动提交脚本),

商户直接将这个表单的String输出到http response中即可。*/

return form;

} catch (AlipayApiException e) {

e.printStackTrace();

}

return null;

}

/**

  • 微信JSAPI支付

  • @param map

  • @return

*/

public static Map<String, String> wxJSAPIPay(Map<String, Object> map) {

SortedMap<String, String> paraMap = new TreeMap<String, String>();

String random = NumberUtils.createRandom(false, 32);

paraMap.put(“appid”, String.valueOf(map.get(“wx_h5_appid”)));// “wxe5703c4e06a09cc8”;

paraMap.put(“attach”, StringUtils.isNull(String.valueOf(map.get(“attach”))) ? “商品购买” : map.get(“attach”) + “”);

paraMap.put(“body”, StringUtils.isNull(String.valueOf(map.get(“body”))) ? “商品购买” : map.get(“body”) + “”);

paraMap.put(“mch_id”, String.valueOf(map.get(“wx_h5_mch_id”)));

paraMap.put(“nonce_str”, random);

paraMap.put(“openid”, String.valueOf(map.get(“openId”)));

paraMap.put(“out_trade_no”, String.valueOf(map.get(“out_trade_no”)));

paraMap.put(“spbill_create_ip”, “172.168.0.1”);//终端ip,在APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。

paraMap.put(“total_fee”, String.valueOf(map.get(“total_fee”)));

paraMap.put(“trade_type”, “JSAPI”);

paraMap.put(“notify_url”, map.get(“wx_jsapi_notify_url”) + “”);

paraMap.put(“sign_type”, “MD5”);

// 签名

RequestHandler reqHandler = new RequestHandler(null, null);

reqHandler.init(String.valueOf(map.get(“wx_h5_appid”)), String.valueOf(map.get(“wx_h5_appsecret”)),

String.valueOf(map.get(“wx_h5_partnerkey”)));

paraMap.put(“sign”, reqHandler.createSign(paraMap));

// 统一下单

String url = “https://api.mch.weixin.qq.com/pay/unifiedorder”;

String xml = WXUtils.ArrayToXml(paraMap);

String prepay_id = “”;

try {

// 提交

prepay_id = getPayPubNo(url, xml);

if (prepay_id.equals(“”)) {

return null;

}

} catch (Exception e) {

e.printStackTrace();

System.out.println(e.getMessage());

return null;

}

SortedMap<String, String> packageParams = new TreeMap<String, String>();

// 需要再次签名,这里要加上时间戳

String timestamp = String.valueOf(System.currentTimeMillis() / 1000);

String prepay_id2 = “prepay_id=” + prepay_id;

String packages = prepay_id2;

packageParams.put(“appId”, String.valueOf(map.get(“wx_h5_appid”)));

packageParams.put(“timeStamp”, timestamp);

packageParams.put(“nonceStr”, random);

packageParams.put(“package”, packages);

packageParams.put(“signType”, “MD5”);

String finalsign = reqHandler.createSign(packageParams);

packageParams.put(“paySign”, finalsign);

return packageParams;

}

/**

  • 根据code获取微信openid

  • @param code

  • @param map

  • @return

*/

public static String getOpenId(String code,Map<String, Object> map) {

WXPubBean wxUserInfo = WXUtils.getWXUserInfo((String) map.get(“wx_pub_appid”), (String) map.get(“wx_pub_appsecret”), code);

BaseLogger.info(“获取微信用户授权信息:”+wxUserInfo.toString());

if(wxUserInfo != null){

return wxUserInfo.getOpenid();

}

return null;

}

/**

  • 提交url给微信获取响应信息

  • @param url

  • @param xml

  • @return

*/

private static String getPayPubNo(String url, String xml) {

String prepay_id = “”;

try {

String result = HttpUtils.getDataByJson(url, xml);

if (result.indexOf(“FAIL”) != -1) {

return prepay_id;

}

Document document = XmlUtils.getDocumentByXml(result);

prepay_id = XmlUtils.getValueByTagName(document, “prepay_id”);

} catch (Exception e) {

e.printStackTrace();

System.out.println(“------------------------------” + e.getMessage());

}

return prepay_id;

Kafka实战笔记

关于这份笔记,为了不影响大家的阅读体验,我只能在文章中展示部分的章节内容和核心截图

image.png

  • Kafka入门
  • 为什么选择Kafka
  • Karka的安装、管理和配置

image.png

  • Kafka的集群
  • 第一个Kafka程序
  • image.png

afka的生产者

image.png

  • Kafka的消费者
  • 深入理解Kafka
  • 可靠的数据传递

image.png

image.png

  • Spring和Kalka的整合
  • Sprinboot和Kafka的整合
  • Kafka实战之削峰填谷
  • 数据管道和流式处理(了解即可)

image.png

  • Kafka实战之削峰填谷

image.png

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

[外链图片转存中…(img-nxy1QKbJ-1715536081410)]

  • Kafka入门
  • 为什么选择Kafka
  • Karka的安装、管理和配置

[外链图片转存中…(img-XQRPxoNX-1715536081410)]

  • Kafka的集群
  • 第一个Kafka程序
  • [外链图片转存中…(img-MuvQPTwB-1715536081411)]

afka的生产者

[外链图片转存中…(img-nOLZNYiI-1715536081411)]

  • Kafka的消费者
  • 深入理解Kafka
  • 可靠的数据传递

[外链图片转存中…(img-iPY2hv7i-1715536081411)]

[外链图片转存中…(img-RuujfD9m-1715536081412)]

  • Spring和Kalka的整合
  • Sprinboot和Kafka的整合
  • Kafka实战之削峰填谷
  • 数据管道和流式处理(了解即可)

[外链图片转存中…(img-WoziwJY4-1715536081412)]

  • Kafka实战之削峰填谷

[外链图片转存中…(img-42OxxNRn-1715536081412)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值