没有网站可以做cpa广告么,做网站公司哪家比较好,学做网站从前端到后端,济南网络优化网址简介
JSAPI支付是指商户通过调用微信支付提供的JSAPI接口#xff0c;在支付场景中调起微信支付模块完成收款。
应用场景
JSAPI支付适用于线下场所、公众号场景和PC网站场景。
商户已有H5商城网站#xff0c;用户通过消息或扫描二维码在微信内打开网页时#xff0c;可以调…简介
JSAPI支付是指商户通过调用微信支付提供的JSAPI接口在支付场景中调起微信支付模块完成收款。
应用场景
JSAPI支付适用于线下场所、公众号场景和PC网站场景。
商户已有H5商城网站用户通过消息或扫描二维码在微信内打开网页时可以调用微信支付完成下单购买的流程。具体操作流程如下
1.商户下发图文消息或者通过自定义菜单吸引用户点击进入商户网页
2.进入商户网页用户选择购买完成选购流程。
3.调起微信支付控件用户开始输入支付密码
4.密码验证通过支付成功。商户后台得到支付成功的通知
5.返回商户页面显示购买成功。该页面由商户自定义
6.微信支付公众号下发支付凭证接入前准备
直接跳转微信支付商户平台 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_1.shtml
生成密钥文件
配置文件
wx:appId: appIdkeyPath: apiclient_key.pemcertPath: apiclient_cert.pemcertP12Path: 暂不用platformCertPath: platform_cert.pemmchId: mchIdapiKey3: 暂不用apiKey: apiKeydomain: https://hous.exchang.cnserialNo: 序列号pom文件
dependencygroupIdcom.github.wechatpay-apiv3/groupIdartifactIdwechatpay-java/artifactIdversion0.2.2/version/dependency代码
配置类
//获取yml中微信配置
Data
ConfigurationProperties(prefix wx)
public class WechatProperties {private String appId;private String keyPath;private String certPath;private String platformCertPath;private String mchId;private String apiKey;private String domain;private String serialNo;
}
//配置类
Configuration
EnableConfigurationProperties(WechatProperties.class)
public class WechatJsapiConfig {private final WechatProperties wechatProperties;public WechatJsapiConfig(WechatProperties wechatProperties) {this.wechatProperties wechatProperties;}Beanpublic RSAConfig rsaConfig() throws IOException {ClassPathResource keyResource new ClassPathResource(wechatProperties.getKeyPath());String apiClientKey keyResource.getFile().getPath();ClassPathResource certResource new ClassPathResource(wechatProperties.getPlatformCertPath());String platformCertResourceKey certResource.getFile().getPath();/*String apiClientKey wechatProperties.getKeyPath();
// ClassPathResource certResource new ClassPathResource(wechatProperties.getPlatformCertPath());String platformCertResourceKey wechatProperties.getPlatformCertPath();*/return new RSAConfig.Builder().merchantId(wechatProperties.getMchId()).privateKeyFromPath(apiClientKey).merchantSerialNumber(wechatProperties.getSerialNo())//平台证书.wechatPayCertificatesFromPath(platformCertResourceKey).build();}Beanpublic JsapiServiceExtension jsapiService() throws IOException {return new JsapiServiceExtension.Builder().config(this.rsaConfig()).build();}Beanpublic NotificationParser notificationParser() throws IOException{ClassPathResource certResource new ClassPathResource(wechatProperties.getPlatformCertPath());String platformCertResourceKey certResource.getFile().getPath();//String platformCertResourceKey wechatProperties.getPlatformCertPath();NotificationConfig config new RSANotificationConfig.Builder().apiV3Key(wechatProperties.getApiKey()).certificatesFromPath(platformCertResourceKey).build();// 初始化 NotificationParserreturn new NotificationParser(config);}Bean(name payRefundService)public RefundService refundService() throws IOException {return new RefundService.Builder().config(this.rsaConfig()).build();}}创建支付单
Slf4j
Service
EnableConfigurationProperties(WechatProperties.class)
public class WechatJsapiPayServiceImpl implements BasePayService {Resourceprivate WechatProperties wechatProperties;Resourceprivate JsapiServiceExtension jsapiService;Value(${spring.application.name})private String serviceName;Resourceprivate MemberDao memberDao;Resourceprivate RedisCache redisCache;Resourceprivate ShopDao shopDao;Overridepublic R? paymentOrder(ListOrder orderList) {BigDecimal total orderList.stream().map(Order::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);Order order orderList.get(0);Long mId order.getMId();Member member memberDao.queryById(mId);Integer payTotal total.multiply(BigDecimal.valueOf(100)).intValue();PrepayRequest prepayRequest new PrepayRequest();prepayRequest.setAppid(wechatProperties.getAppId());prepayRequest.setMchid(wechatProperties.getMchId());prepayRequest.setDescription(供应链下单);prepayRequest.setOutTradeNo(order.getBatchSn());prepayRequest.setNotifyUrl(wechatProperties.getDomain() /callback/wechat/pay);prepayRequest.setAttach(1);prepayRequest.setTimeExpire(this.getTimeExpire());Amount amount new Amount();amount.setTotal(payTotal);Payer payer new Payer();payer.setOpenid(member.getOpenId());prepayRequest.setAmount(amount);prepayRequest.setPayer(payer);log.info(创建预支付单入参【{}】, JSONObject.toJSONString(prepayRequest));try {PrepayWithRequestPaymentResponse response jsapiService.prepayWithRequestPayment(prepayRequest);log.info(创建预支付单并生成二维码成功出参【{}】, JSONObject.toJSONString(response));//未支付监听redisCache.setCacheObject(RedisConstants.ORDER_PAY_RESULT.concat(order.getBatchSn()),JSONObject.toJSONString(response), 10, TimeUnit.MINUTES);redisCache.setCacheObject(RedisConstants.ORDER_NOT_PAY_LISTENER.concat(order.getBatchSn()),NumberUtils.INTEGER_ZERO, 10, TimeUnit.MINUTES);//发送未支付消息redisCache.setCacheObject(RedisConstants.ORDER_MSG_LISTENER.concat(order.getBatchSn()),NumberUtils.INTEGER_ZERO, 2, TimeUnit.MINUTES);return R.ok(response);} catch (HttpException e) { // 发送HTTP请求失败log.error(发送HTTP请求失败:{}, e.getHttpRequest());return R.fail(发送HTTP请求失败);} catch (ServiceException e) { // 服务返回状态小于200或大于等于300例如500log.error(微信支付返回状态异常{}, e.getResponseBody());return R.fail(微信支付返回状态异常);} catch (MalformedMessageException e) { // 服务返回成功返回体类型不合法或者解析返回体失败log.error(返回类型不合法:{}, e.getMessage());return R.fail(返回类型不合法);}}Overridepublic void closeOrder(String outTradeNo) {CloseOrderRequest closeOrderRequest new CloseOrderRequest();closeOrderRequest.setMchid(wechatProperties.getMchId());closeOrderRequest.setOutTradeNo(outTradeNo);jsapiService.closeOrder(closeOrderRequest);log.info(订单关闭成功入参【{}】, JSONObject.toJSONString(closeOrderRequest));}Overridepublic OptionalTransaction getOrderInfo(String outTradeNo) {QueryOrderByOutTradeNoRequest request new QueryOrderByOutTradeNoRequest();request.setOutTradeNo(outTradeNo);request.setMchid(wechatProperties.getMchId());Transaction transaction jsapiService.queryOrderByOutTradeNo(request);if (Objects.isNull(transaction)) {return Optional.empty();}return Optional.of(transaction);}private String getTimeExpire(){//过期时间 RFC 3339格式SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-ddTHH:mm:ssXXX);//支付订单过期时间return sdf.format(new Date(System.currentTimeMillis() 1000 * 60 * 5));}}创建退款单
Slf4j
Service
EnableConfigurationProperties(WechatProperties.class)
public class WechatRefundServiceImpl implements BaseRefundService {Resourceprivate RefundService refundService;Resourceprivate WechatProperties wechatProperties;Value(${spring.application.name:scm-ofc-system})private String serviceName;Resourceprivate OrderDao orderDao;Resourceprivate OrderItemDao orderItemDao;Resourceprivate ShopDao shopDao;Overridepublic R? refundOrder(OrderRefund orderRefund) {try {BigDecimal refundAmount orderRefund.getRefundAmount();Long orderId orderRefund.getOrderId();Order order orderDao.queryById(orderId);//退款金额long refundTotal refundAmount.multiply(BigDecimal.valueOf(100)).longValue();//原支付金额String batchSn order.getBatchSn();OrderDTO params new OrderDTO();params.setBatchSn(batchSn);ListOrder orders orderDao.selectOrderList(params);BigDecimal officialReceipts orders.stream().map(Order::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);long payTotal officialReceipts.multiply(BigDecimal.valueOf(100)).longValue();//创建微信退款单CreateRequest createRequest new CreateRequest();AmountReq amountReq new AmountReq();amountReq.setCurrency(CNY);amountReq.setTotal(payTotal);amountReq.setRefund(refundTotal);createRequest.setOutTradeNo(batchSn);createRequest.setAmount(amountReq);createRequest.setOutRefundNo(orderRefund.getRefundSn());createRequest.setNotifyUrl(wechatProperties.getDomain() / serviceName /callback/wechat/refund);log.info(退款单入参{}, JSONObject.toJSONString(createRequest));Refund refund refundService.create(createRequest);log.info(创建退款单成功{}, JSONObject.toJSONString(refund));if (Objects.isNull(refund)) {log.error(退款异常参数{}, JSONObject.toJSONString(createRequest));return R.fail(500, 退款异常请求微信返回值为null参数 JSONObject.toJSONString(createRequest));}if (Objects.equals(refund.getStatus(), Status.SUCCESS)) {return R.ok(refund);}} catch (Exception e) {log.error(退款异常{}, e.getMessage());return R.fail(500, 退款异常请求微信报错 e.getMessage());}return R.ok();}}支付与退款回调
Slf4j
Service
public class CallbackServiceImpl implements CallbackService {Resourceprivate NotificationParser notificationParser;Resourceprivate RedisCache redisCache;Resourceprivate OrderService orderService;Resourceprivate BillDao billDao;Resourceprivate ShopAccountDao shopAccountDao;Resourceprivate OrderScmService orderScmService;Resourceprivate OrderRefundDao orderRefundDao;Resourceprivate ShopSkuService shopSkuService;Resourceprivate OrderItemDao orderItemDao;Resourceprivate MessageService messageService;OverrideTransactional(rollbackFor Exception.class)public void wechatPayCallback(HttpServletRequest request, HttpServletResponse response) {try {log.info(微信native支付回调通知);Transaction transaction this.verifyAndDecrypt(request, Transaction.class);log.info(验证签名成功{}, JSONObject.toJSONString(transaction));Transaction.TradeStateEnum tradeState transaction.getTradeState();if (!Objects.equals(tradeState, Transaction.TradeStateEnum.SUCCESS)) {return;}String outTradeNo transaction.getOutTradeNo();log.info(支付回调执行成功待支付-待发货);} catch (Exception e) {log.error(支付回调异常{}, e.getMessage());}}Overridepublic void wechatRefundCallback(HttpServletRequest request, HttpServletResponse response) {log.info(微信native退款回调通知);RefundNotification refundNotification this.verifyAndDecrypt(request, RefundNotification.class);Status refundStatus refundNotification.getRefundStatus();if (!Objects.equals(refundStatus, Status.SUCCESS)) {return;}//执行退款业务}/*** 获取供应链订单id* param data* param orderList* return*/private MapLong, String getOrderIdMap(OrderByThirdIdVO data,ListOrder orderList){ListOrderSkuDetailVO skus data.getSkus();MapString, String skuOrderIdMap skus.stream().collect(Collectors.toMap(OrderSkuDetailVO::getSku, OrderSkuDetailVO::getOrderId));ListOrderItem orderItems orderList.stream().map(Order::getOrderItem).collect(Collectors.toList());return orderItems.stream().map(item - {String originId item.getOriginId();String orderId skuOrderIdMap.get(originId);return new DefaultKeyValue(item.getOrderId(), orderId);}).collect(Collectors.toMap(DefaultKeyValue::getKey, DefaultKeyValue::getValue));}/*** 验证并解密报文** param request*/private T T verifyAndDecrypt(HttpServletRequest request, ClassT clazz) {String timestamp request.getHeader(Wechatpay-Timestamp);String nonce request.getHeader(Wechatpay-Nonce);String serialNo request.getHeader(Wechatpay-Serial);String signature request.getHeader(Wechatpay-Signature);String signType request.getHeader(Wechatpay-Signature-Type);String body this.getBody(request);log.info(\n请求头信息:\n Wechatpay-Timestamp{},\n Wechatpay-Nonce{},\n Wechatpay-Serial{},\n Wechatpay-Signature{},\n Wechatpay-Signature-Type{},\n body: {},timestamp, nonce, serialNo, signature, signType, body);RequestParam requestParam new RequestParam.Builder().serialNumber(serialNo).nonce(nonce).signature(signature).timestamp(timestamp).signType(signType).body(body).build();return notificationParser.parse(requestParam, clazz);}/*** 获取请求体内容** param request* return*/private String getBody(HttpServletRequest request) {BufferedReader reader;String body ;try {reader request.getReader();String line;StringBuilder inputString new StringBuilder();while ((line reader.readLine()) ! null) {inputString.append(line);}body inputString.toString();} catch (IOException e) {e.printStackTrace();}return body;}}以上就是微信jsapi支付的对接仅供参考