【畅购商城】微信支付之支付模块

简介: 【畅购商城】微信支付之支付模块

支付页面

步骤一:创建 flow3.vue组件


1fca45fa2df24fe08872a0bcf72aa76f.png

步骤二:引入第三方资源(js、css)


<script>
import TopNav from '../components/TopNav'
import Footer from '../components/Footer'
export default {
  head: {
    title: '首页',
    link: [
      {rel:'stylesheet',href: '/style/success.css'},
    ],
    script: [
    ]
  },
  components: {
    TopNav,
    Footer,
  },
}
</script>


接口


POST http://localhost:10010/order-service/pay
{
  "sn" : "1255513323915579400"
}


后端实现

步骤一:编写 PayRequest,用于封装数据


6c9571a336454ad297e79704bee87499.png

package com.czxy.changgou4.vo;
import lombok.Data;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Data
public class PayRequest {
    private Long sn;
}

步骤二:检查order服务,yml文件中是否有微信配置

da9b2e9c46e34baca710fb008035a991.png

sc:
  pay:
    appID: wx8397f8696b538317
    mchID: 1473426802
    key: T6m9iK73b0kn9g5v426MKfHQH7X8rKwb
    httpConnectTimeoutMs: 5000
    httpReadTimeoutMs: 10000

步骤三:编写PayProperties,用于加载微信配置

51ca367bd5504c77b5544d50f2024669.png

package com.czxy.changgou4.config;
import com.github.wxpay.sdk.WXPayConfig;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.io.InputStream;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Data
@ConfigurationProperties(prefix = "sc.pay")
public class PayProperties implements WXPayConfig {
    private String appID;               // 公众账号ID
    private String mchID;               // 商户号
    private String key;                 // 生成签名的密钥
    private int httpConnectTimeoutMs;   // 连接超时时间
    private int httpReadTimeoutMs;      // 读取超时时间
    @Override
    public InputStream getCertStream() {
        //加载证书,需要通过账号中心生成
        return null;
    }
}

步骤四:编写PayState,自定义支付状态


4c40a211f4f348719bfa81c9ed48852d.png

package com.czxy.changgou4.utils;
import lombok.Getter;
/**
 * 自定义支付状态,微信支持多种状态,此处统一四种:
 * SUCCESS—支付成功、NOTPAY—未支付、CLOSED—已关闭、PAYERROR--支付失败
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Getter
public enum PayState {
    NOT_PAY(0,"未支付"),SUCCESS(1,"支付成功"),CLOSED(2,"已关闭"),PAY_ERROR(3,"支付失败");
    PayState(int code,String desc) {
        this.code = code;
        this.desc = desc;
    }
    private int code;           //自定义编码
    private String desc;        //描述信息
}

步骤五:编写PayHelper,用于微信操作的工具类

package com.czxy.changgou4.utils;
import com.czxy.changgou4.config.PayProperties;
import com.github.wxpay.sdk.WXPay;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Component
@EnableConfigurationProperties(PayProperties.class)
public class PayHelper {
    private WXPay wxPay;
    @Bean
    public WXPay wxPay(PayProperties payProperties){
        if(wxPay == null){
            wxPay = new WXPay(payProperties);
        }
        return wxPay;
    }
    private static final Logger logger = LoggerFactory.getLogger(PayHelper.class);
    public PayHelper() {
    }
    public PayHelper(PayProperties payProperties) {
        wxPay = new WXPay(payProperties);
    }
    public String createPayUrl(Long sn) {
        String key = "pay.url." + sn;
        try {
            Map<String, String> data = new HashMap<>();
            // 商品描述
            data.put("body", "商城测试");
            // 订单号
            data.put("out_trade_no", sn.toString());
            //货币
            data.put("fee_type", "CNY");
            //金额,单位是分
            data.put("total_fee", "1");
            //调用微信支付的终端IP(商城的IP)
            data.put("spbill_create_ip", "127.0.0.1");
            //回调地址
            data.put("notify_url", "http://test.jingxi.com/wxpay/notify");
            // 交易类型为扫码支付
            data.put("trade_type", "NATIVE");
            //商品id,使用假数据
            data.put("product_id", "1234567");
            Map<String, String> result = this.wxPay.unifiedOrder(data);
            if ("SUCCESS".equals(result.get("return_code"))) {
                if("SUCCESS".equals(result.get("result_code"))){
                    String url = result.get("code_url");
                    return url;
                } else {
                    logger.error("创建预交易订单失败,错误信息:{}", result.get("err_code_des"));
                    return null;
                }
            } else {
                logger.error("创建预交易订单失败,错误信息:{}", result.get("return_msg"));
                return null;
            }
        } catch (Exception e) {
            logger.error("创建预交易订单异常", e);
            return null;
        }
    }
    /**
     * 查询订单状态
     * 交易状态参考:(trade_state)
     SUCCESS—支付成功
     REFUND—转入退款
     NOTPAY—未支付
     CLOSED—已关闭
     REVOKED—已撤销(付款码支付)
     USERPAYING--用户支付中(付款码支付)
     PAYERROR--支付失败(其他原因,如银行返回失败)
     * @param sn
     * @return
     */
    public PayState queryOrder(Long sn) {
        Map<String, String> data = new HashMap<>();
        // 订单号
        data.put("out_trade_no", sn.toString());
        try {
            Map<String, String> result = this.wxPay.orderQuery(data);
            if("SUCCESS".equals(result.get("return_code"))){
                if("SUCCESS".equals(result.get("result_code"))) {
                    String tradeState = result.get("trade_state");
                    if ("SUCCESS".equals(tradeState)) {
                        return PayState.SUCCESS;
                    }
                    if ("NOTPAY".equals(tradeState)) {
                        return PayState.NOT_PAY;
                    }
                    if ("CLOSED".equals(tradeState)) {
                        return PayState.CLOSED;
                    }
                }
            }
            return PayState.PAY_ERROR;
        } catch (Exception e) {
            logger.error("查询订单状态异常", e);
            return PayState.PAY_ERROR;
        }
    }
}

步骤五:编写PayService,调用工具类,用于生成支付接口


3d878ff46c5449559e53b80689420546.png


package com.czxy.changgou4.service;
import com.czxy.changgou4.vo.PayRequest;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
public interface PayService {
    public String pay(PayRequest payRequest);
}
package com.czxy.changgou4.service.impl;
import com.czxy.changgou4.service.PayService;
import com.czxy.changgou4.utils.PayHelper;
import com.czxy.changgou4.vo.PayRequest;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Service
public class PayServiceImpl implements PayService {
    @Resource
    private PayHelper payHelper;
    @Override
    public String pay(PayRequest payRequest) {
        //根据sn查询订单
        //获得微信支付路径
        String payUrl = payHelper.createPayUrl(payRequest.getSn());
        //返回支付路径
        return payUrl;
    }
}

步骤六:编写PayController,根据sn生产微信支付路径

5de85d9d4bbb4a9da59491d03c7a66f0.png

package com.czxy.changgou4.controller;
import com.czxy.changgou4.service.PayService;
import com.czxy.changgou4.vo.BaseResult;
import com.czxy.changgou4.vo.PayRequest;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@RestController
@RequestMapping("/pay")
public class PayController {
    @Resource
    private PayService payService;
    @PostMapping
    public BaseResult pay(@RequestBody PayRequest payRequest){
        //获得支付路径
        String payUrl = payService.pay(payRequest);
        //返回
        return BaseResult.ok("二维码生产成功").append("wxurl",payUrl);
    }
}


前端实现

步骤一:修改apiclient.js文件,生成位置支付路径


16af390dd6f24d5392d09f4a9521a138.png

  pay : ( params ) => {
    return axios.post("/order-service/pay" ,params )
  }

步骤二:拷贝qrcode.min.js 用于生成二维码


07747d31731247f48e6a167b03c669fa.png

步骤三:导入qrcode.min.js

57990fcbf19049a8946d8b52050cce36.png

 script: [
      { type: 'text/javascript', src: '/js/qrcode.min.js' }
    ]

步骤四:页面加载成功,把微信支付路径生产二维码

  data() {
    return {
      sn: this.$route.query.sn,
    }
  },
  async mounted() {
    let {data} = await this.$request.pay({"sn":this.sn})
    new QRCode( document.getElementById("qrcode") , data.other.wxurl )
  },

步骤五:确定二维码生成的位置


003f0f7c887b4b6988cd2d76f407d266.png

<p>
   <div id="qrcode" style="width:256px;margin: 0 auto;"></div>
</p>

步骤六:优化,添加样式,

<style>
  #qrcode img {
    background-color: #fff;
    padding: 6px;
  }
</style>
相关文章
|
XML 移动开发 JavaScript
【畅购商城】微信支付模块之微信支付二维码
【畅购商城】微信支付模块之微信支付二维码
182 0
【畅购商城】微信支付模块之微信支付二维码
|
23天前
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
354 7
|
23天前
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
429 1
|
1月前
|
小程序 前端开发 测试技术
微信小程序的开发完整流程是什么?
微信小程序的开发完整流程是什么?
97 7
ly~
|
2月前
|
存储 供应链 小程序
除了微信小程序,PHP 还可以用于开发哪些类型的小程序?
除了微信小程序,PHP 还可用于开发多种类型的小程序,包括支付宝小程序、百度智能小程序、抖音小程序、企业内部小程序及行业特定小程序。在电商、生活服务、资讯、工具、娱乐、营销等领域,PHP 能有效管理商品信息、订单处理、支付接口、内容抓取、复杂计算、游戏数据、活动规则等多种业务。同时,在企业内部,PHP 可提升工作效率,实现审批流程、文件共享、生产计划等功能;在医疗和教育等行业,PHP 能管理患者信息、在线问诊、课程资源、成绩查询等重要数据。
ly~
75 6
|
27天前
|
缓存 小程序 索引
uni-app开发微信小程序时vant组件van-tabs的使用陷阱及解决方案
uni-app开发微信小程序时vant组件van-tabs的使用陷阱及解决方案
149 1
|
1月前
|
小程序 前端开发 数据安全/隐私保护
微信小程序全栈开发中的身份认证与授权机制
【10月更文挑战第3天】随着移动互联网的发展,微信小程序凭借便捷的用户体验和强大的社交传播能力,成为企业拓展业务的新渠道。本文探讨了小程序全栈开发中的身份认证与授权机制,包括手机号码验证、微信登录、第三方登录及角色权限控制等方法,并强调了安全性、用户体验和合规性的重要性,帮助开发者更好地理解和应用这一关键技术。
51 5
|
1月前
|
小程序 前端开发 JavaScript
微信小程序全栈开发中的PWA技术应用
【10月更文挑战第3天】微信小程序作为新兴应用形态,凭借便捷体验与社交传播能力,成为企业拓展业务的新渠道。本文探讨了微信小程序全栈开发中的PWA技术应用,包括离线访问、后台运行、桌面图标及原生体验等方面,助力开发者提升小程序性能与用户体验。PWA技术在不同平台的兼容性、性能优化及用户体验是实践中需注意的关键点。
53 5
|
28天前
|
小程序 JavaScript API
微信小程序开发之:保存图片到手机,使用uni-app 开发小程序;还有微信原生保存图片到手机
这篇文章介绍了如何在uni-app和微信小程序中实现将图片保存到用户手机相册的功能。
437 0
微信小程序开发之:保存图片到手机,使用uni-app 开发小程序;还有微信原生保存图片到手机
|
18天前
|
存储 小程序 安全
微信的开发管理都需要配置什么?
【10月更文挑战第17天】微信的开发管理都需要配置什么?
27 0

热门文章

最新文章