开发公司小程序开发调用微信支付以及微信回调地址配置

开发公司首先观看微信提供的文档

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1

开发公司清楚调用微信支付必须开发公司传递的参数

开发公司因为微信提供了小程序开发公司唤起微信支付的方法,开发公司后端只需要传递对应的开发公司参数给前端即可

开发公司首先在程序中配置申请的固定参数

  1. wx.open.app_id=用户的appid
  2. wx.open.app_secret=这是做登陆用的
  3. weixin.pay.partner=商户号
  4. wexxin.pay.partenerkey=商户号秘钥

编写工具类实现对固定值的读取

  1. @Component
  2. //@PropertySource("classpath:application.properties")
  3. public class ConstantPropertiesUtil implements InitializingBean {
  4. //读取配置文件并赋值
  5. @Value("${wx.open.app_id}")
  6. private String appId;
  7. @Value("${wx.open.app_secret}")
  8. private String appSecret;
  9. @Value("{weixin.pay.partner}")
  10. private String partner;
  11. @Value("{wexxin.pay.partenerkey}")
  12. private String partenerkey;
  13. public static String WX_OPEN_APP_ID;
  14. public static String WX_OPEN_APP_SECRET;
  15. public static String PARTNER;
  16. public static String PARTNERKET;
  17. @Override
  18. public void afterPropertiesSet() throws Exception {
  19. WX_OPEN_APP_ID = appId;
  20. WX_OPEN_APP_SECRET = appSecret;
  21. PARTNER = partner;
  22. PARTNERKET = partenerkey;
  23. }
  24. }

当用户点击购买会生成订单,这里代码省略

点击登陆时调用后端传给前端需要的值

对应微信文档https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

 可以看到,除了一些固定值,需要我们自己处理的有

签名:根据文档可以发现签名是有一定要求的

 简单来说就将其他传入固定值字段进行排序拼接,在根据商家号的key进行加密处理。

支付接口

  1. @Autowired
  2. private WXService wxService;
  3. @GetMapping("pay")
  4. public R creatNative(Integer orderid){
  5. try {
  6. Map map = wxService.payment(orderid);
  7. return R.ok().data(map);
  8. } catch (UnsupportedEncodingException e) {
  9. return R.error().message("支付失败");
  10. }
  11. }

编写service逻辑,根据文档进行传值

  1. @Service
  2. public class WXServiceImpl implements WXService {
  3. @Autowired
  4. private OrderService orderService;
  5. @Override
  6. public Map payment(Integer orderid) throws UnsupportedEncodingException {
  7. //封装传递微信地址参数
  8. Map paramMap = new HashMap();
  9. paramMap.put("appid", ConstantPropertiesUtil.WX_OPEN_APP_ID); //公众号id
  10. paramMap.put("mch_id", ConstantPropertiesUtil.PARTNER); //商户号
  11. paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串,调用工具类
  12. paramMap.put("out_trade_no", orderid); //订单流水号
  13. Order order = orderService.getById(orderid);
  14. paramMap.put("total_fee", order.getPayment()); //金额
  15. paramMap.put("spbill_create_ip", "127.0.0.1"); //终端ip
  16. paramMap.put("notify_url", "http://XXXXX/weixin/callBack");//回调地址
  17. paramMap.put("body",order.getProductname()); //商品名称
  18. paramMap.put("timeStamp", WXUtil.getCurrentTimestamp()+"");//获取当前时间戳,单位秒
  19. String sign = WXUtil.genSignature(ConstantPropertiesUtil.PARTNERKET,paramMap); //sing
  20. paramMap.put("sign", sign); //签名
  21. return paramMap;
  22. }
  23. }

签名工具类,以及时间戳方法

  1. public class WXUtil {
  2. public static String genSignature(String secretKey, Map<String, String> params) throws UnsupportedEncodingException {
  3. if (secretKey == null || params == null || params.size() == 0) {
  4. return "";
  5. }
  6. // 1. 参数名按照ASCII码表升序排序
  7. String[] keys = params.keySet().toArray(new String[0]);
  8. Arrays.sort(keys);
  9. // 2. 按照排序拼接参数名与参数值
  10. StringBuffer paramBuffer = new StringBuffer();
  11. for (String key : keys) {
  12. paramBuffer.append("&"+key).append(params.get(key) == null ? "" : "="+params.get(key));
  13. }
  14. // 3. 将secretKey拼接到最后
  15. paramBuffer=paramBuffer.append("&key="+secretKey);
  16. String pa =paramBuffer.substring(1);
  17. // 4. MD5是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32个十六进制字符。
  18. return DigestUtils.md5Hex(pa.getBytes("UTF-8")).toUpperCase();
  19. }
  20. /**
  21. * 获取当前时间戳,单位秒
  22. * @return
  23. */
  24. public static long getCurrentTimestamp() {
  25. return System.currentTimeMillis()/1000;
  26. }
  27. /**
  28. * 获取当前时间戳,单位毫秒
  29. * @return
  30. */
  31. public static long getCurrentTimestampMs() {
  32. return System.currentTimeMillis();
  33. }
  34. }

此时即可完成支付,微信支付后,微信会给我们地址进行发送信息,由此我们可以判断支付状态以及获取微信支付返回的参数

回调接口

  1. //回调接口
  2. @RequestMapping("callBack")
  3. public String callBack(HttpServletRequest request, HttpServletResponse response) throws Exception{
  4. System.out.println("接口已被调用");
  5. ServletInputStream inputStream = request.getInputStream();
  6. String notifyXml = StreamUtils.inputStream2String(inputStream, "utf-8");
  7. System.out.println(notifyXml);
  8. // 解析返回结果
  9. Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyXml);
  10. // 判断支付是否成功
  11. if ("SUCCESS".equals(notifyMap.get("result_code"))) {
  12. //编写自己的实现逻辑
  13. // 支付成功:给微信发送我已接收通知的响应
  14. // 创建响应对象
  15. Map<String, String> returnMap = new HashMap<>();
  16. returnMap.put("return_code", "SUCCESS");
  17. returnMap.put("return_msg", "OK");
  18. String returnXml = WXPayUtil.mapToXml(returnMap);
  19. response.setContentType("text/xml");
  20. System.out.println("支付成功");
  21. return returnXml;
  22. }
  23. }
  24. // 创建响应对象:微信接收到校验失败的结果后,会反复的调用当前回调函数
  25. Map<String, String> returnMap = new HashMap<>();
  26. returnMap.put("return_code", "FAIL");
  27. returnMap.put("return_msg", "");
  28. String returnXml = WXPayUtil.mapToXml(returnMap);
  29. response.setContentType("text/xml");
  30. System.out.println("校验失败");
  31. return returnXml;
  32. }

接收输入流转换工具类

  1. public class StreamUtils {
  2. private static int _buffer_size = 1024;
  3. /**
  4. * InputStream流转换成String字符串
  5. * @param inStream InputStream流
  6. * @param encoding 编码格式
  7. * @return String字符串
  8. */
  9. public static String inputStream2String(InputStream inStream, String encoding){
  10. String result = null;
  11. ByteArrayOutputStream outStream = null;
  12. try {
  13. if(inStream != null){
  14. outStream = new ByteArrayOutputStream();
  15. byte[] tempBytes = new byte[_buffer_size];
  16. int count = -1;
  17. while((count = inStream.read(tempBytes, 0, _buffer_size)) != -1){
  18. outStream.write(tempBytes, 0, count);
  19. }
  20. tempBytes = null;
  21. outStream.flush();
  22. result = new String(outStream.toByteArray(), encoding);
  23. outStream.close();
  24. }
  25. } catch (Exception e) {
  26. result = null;
  27. } finally {
  28. try {
  29. if(inStream != null) {
  30. inStream.close();
  31. inStream = null;
  32. }
  33. if(outStream != null) {
  34. outStream.close();
  35. outStream = null;
  36. }
  37. } catch (IOException e) {
  38. e.printStackTrace();
  39. }
  40. }
  41. return result;
  42. }
  43. }
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发