微信小程序支付 + 公眾號支付 (含源碼)


文:微信小程序支付 + 公眾號支付 (含源碼)

為啥會有這篇文章

  最近換了個公司,接手了個別人的老項目,從git上拉取代碼,導入idea時,我TM快哭了。。。

我瞅了眼微信支付相關代碼,頓時想上去就是一Jao ! 我看到了這樣的代碼:

我靠,你這么寫,倒是一時爽;維護可就爽歪歪咯!!

怎么辦,怎么辦。。。

支付模塊重構

別的先不說,重構之前我們先樓一眼微信部分支付流程圖

注:上面是部分支付流程圖(完整圖片,可上官網查看)

官網:
https://pay.weixin.qq.com/wiki/doc/api/index.html

重構項目全貌

  • 項目架構:springboot + mybatis

  • 數據庫:mysql

  • 開發環境:jdk8、idea

  • 支付:微信小程序、公眾號

重構之后,代碼簡介、清爽,它不香嗎!!

微信支付實操

1、controller層 

/**
* Create By CodeCow on 2020/7/19.
*/
@Slf4j
@RestController
@RequestMapping("/pay")
public class WeiXinPayController {

@Resource
private WeiXinPayService weiXinPayService;

@ApiOperation(value = "微信支付(公眾號/小程序)", response = WechatPayMiniRespDTO.class)
@ApiResponses({@ApiResponse(code = 0, message = "Success"), @ApiResponse(code = 500, message = "failed")})
@PostMapping(value = "/miniPay", consumes = "application/json", produces = "application/json")
public RespResult<WechatPayMiniRespDTO> weChatMiniBookOrderPay(@RequestBody @Valid WechatPayReqDTO wechatPayReqDTO) {
try {
return weiXinPayService.weChatBookOrderPay(wechatPayReqDTO);
} catch (Exception e) {
log.error("weChatBookOrderPay error: ", e);
return RespResult.error(RespResultEnum.WEIXIN_PAY_ERROR.getCode(),
RespResultEnum.WEIXIN_PAY_ERROR.getMessage() + e.getMessage());
}
}
}

2、service層

/**
* Create By CodeCow on 2020/7/19.
*/
public interface WeiXinPayService {

RespResult weChatBookOrderPay(WechatPayReqDTO wechatPayReqDTO);
}

 

快快快,拿出小本本,提起紙筆。。。開始裝B

 

3、serviceImpl層

/**
* Create By CodeCow on 2020/7/19.
*/
@Slf4j
@Service
public class WeiXinPayServiceImpl implements WeiXinPayService {

@Resource
private UserMapper userMapper; //用戶mapper

@Resource
private WechatConfig wechatConfig; //微信配置(在最后)

@Resource
private OrderMapper orderMapper; //訂單mapper

@Resource
private CommonTemplateService templateService; // 自己封裝的restTemplate(在最后)

@Override
public RespResult weChatBookOrderPay(WechatPayReqDTO wechatPayReqDTO) {
UserDO userDO = userMapper.selectById(wechatPayReqDTO.getUserId());
Long orderCode = TimeUtil.getTimestamp(); //生成隨機訂單號
WechatBookOrderReqDTO wechatBookOrderReqDTO //封裝微信下單請求參數(此方法在下面)
= getBookOrderReqDTO(wechatPayReqDTO, orderCode, userDO);
String sign = //生成簽名(簽名工具類在最后)
WeChatSignUtil.getSign(wechatBookOrderReqDTO, wechatConfig.getApiKey());
wechatBookOrderReqDTO.setSign(sign);
String reqXML = XstreamUtil.objectToXml(wechatBookOrderReqDTO); //把請求參數轉化成 xml 格式
log.info(">>>> reqXML >>>>:\n " + reqXML); //打印日志
ResponseEntity<String> responseEntity = //使用自己封裝的restTemplate向微信發起請求
templateService.executePost(reqXML, wechatConfig.getBookOrderUrl());
if (responseEntity.getStatusCode().value() != HttpStatus.OK.value()) { //判斷請求是否成功
return RespResult.error(RespResultEnum.ORDER_ERROR.getCode(),
RespResultEnum.ORDER_ERROR.getMessage() + responseEntity.getBody());
}
WechatBookOrderRespDTO wechatBookOrderRespDTO = // 把微信返回的參數封裝到自己DTO中(DTO在最后)
XstreamUtil.xmlToObject(responseEntity.getBody(), WechatBookOrderRespDTO.class);
if (wechatBookOrderRespDTO.getXmlReturnCode().equals(WechatRespEnum.WECHAT_RETURN_CODE_FAIL.getCode())) { //判斷微信響應結果
return RespResult.error(RespResultEnum.ORDER_RETURN_ERROR.getCode(),
RespResultEnum.ORDER_RETURN_ERROR.getMessage() + wechatBookOrderRespDTO.getXmlReturnMsg());
} else if (wechatBookOrderRespDTO.getXmlResultCode().equals(WechatRespEnum.WECHAT_RESULT_CODE_FAIL.getCode())) {
return RespResult.error(RespResultEnum.ORDER_RESULT_ERROR.getCode(),
RespResultEnum.ORDER_RESULT_ERROR.getMessage() + wechatBookOrderRespDTO.getXmlErrCodeDes());
}
insertRefuelOrder(userDO, wechatPayReqDTO, orderCode); //向數據庫保存訂單信息(方法在下面)
String nonceStr = WeChatSignUtil.getNonceStr();
long timestamp = TimeUtil.getTimestamp();
String paySign = WeChatPaySignUtil.getPaySign(wechatConfig.getAppId(), nonceStr, // 重新生成簽名(前段調起支付需要)
wechatBookOrderRespDTO.getXmlPrepayId(), wechatConfig.getSignType(), String.valueOf(timestamp), wechatConfig.getApiKey());
WechatPayMiniRespDTO wechatPayMiniRespDTO = // 返回前段支付需要的DTO(DTO在最后)
getPayMiniRespDTO(paySign, nonceStr, timestamp, orderCode, wechatBookOrderRespDTO);
return RespResult.success(wechatPayMiniRespDTO); // 返回數據
}

private WechatBookOrderReqDTO getBookOrderReqDTO(WechatPayReqDTO wechatPayReqDTO, Long orderCode, UserDO userDO) {
return WechatBookOrderReqDTO.builder()
.appid(wechatConfig.getAppId())
.mch_id((wechatConfig.getMchId()))
.openid(userDO.getOpenid())
.trade_type(TradeTypeEnum.WECHAT_JSAPI.getType())
.nonce_str(WeChatSignUtil.getNonceStr())
.sign_type(wechatConfig.getSignType())
.body(wechatPayReqDTO.getDescription())
.out_trade_no(String.valueOf(orderCode))
.total_fee(wechatPayReqDTO.getTotalFee())
.spbill_create_ip(wechatPayReqDTO.getIp())
.time_start(String.valueOf(TimeUtil.getTimestamp()))
.notify_url(wechatConfig.getNotifyUrl())
.build();
}

private void insertRefuelOrder(UserDO userDO, WechatPayReqDTO wechatPayReqDTO, Long orderCode) {
OrderDO orderDO = OrderDO.builder()
.id(TimeUtil.getTimestamp())
.userId(String.valueOf(userDO.getUserId()))
.orderCode(String.valueOf(orderCode))
.status("0")
.totalFee(new BigDecimal(wechatPayReqDTO.getTotalFee()))
.payType("1") //支付類型(1-微信,2-支付寶)
.detail(wechatPayReqDTO.getDescription())
.createTime(TimeUtil.now())
.build();
orderMapper.insert(orderDO);
}

private WechatPayMiniRespDTO getPayMiniRespDTO(String paySign, String nonceStr, long timestamp,
Long orderCode, WechatBookOrderRespDTO wechatBookOrderRespDTO) {
return WechatPayMiniRespDTO.builder()
.paySign(paySign)
.nonceStr(nonceStr)
.outTradeNo(String.valueOf(orderCode))
.ppackage(ColumnNames.PARAM_PREPAY_ID + wechatBookOrderRespDTO.getXmlPrepayId())
.signType(wechatConfig.getSignType())
.timeStamp(String.valueOf(timestamp))
.tradeType(wechatBookOrderRespDTO.getXmlTradeType())
.build();
}
}

4、WechatPayMiniRespDTO

/**
* Create By CodeCow on 2020/7/19.
*/
@Data
@Builder
@ApiModel("微信小程序/公眾號支付返回參數")
public class WechatPayMiniRespDTO {

@ApiModelProperty(value = "時間戳從1970年1月1日00:00:00至今的秒數,即當前的時間", required = true)
private String timeStamp;

@ApiModelProperty(value = "隨機字符串,不長於32位", required = true)
private String nonceStr;

@ApiModelProperty(value = "統一下單接口返回的 prepay_id 參數值", required = true)
@JsonProperty(value = "package")
private String ppackage;

@ApiModelProperty(value = "MD5", required = true)
private String signType;

@ApiModelProperty(value = "前端調用微信支付功能所需簽名", required = true)
private String paySign;

@ApiModelProperty(value = "交易類型", required = true)
private String tradeType;

@ApiModelProperty(value = "訂單號")
private String outTradeNo;

}

 

代碼實在有點多,寫到這,手都酸了。。。

好文推薦

==>:微信公眾號授權+獲取用戶信息+jwt登錄 (含源碼)

==>: 微信小程序授權+獲取用戶手機號+jwt登錄 (含源碼)

 

小聲BB

由於支付代碼比較多,小編就不挨個粘貼了
若需要完整 “ 源碼 ” 可在公眾號內回復“ 微信支付 ”,發百度網盤

弱弱問一句

看完了,支付還用自己寫嗎

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM