精华内容
下载资源
问答
  • 微信支付WXPayEntryActivity 不回调

    万次阅读 2018-10-16 10:58:51
    微信支付同步回调不回调问题记录 1.微信支付官方文档 ... 第三方的东西都是比较简单的,直接看官方...有同步回调结果异步回调结果,一般官方建议以异步回调结果为准,所以我们在同步回调结果判断支付成功后,去请求...

    微信支付同步回调不回调问题记录

    1.微信支付官方文档

    https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5

    第三方的东西都是比较简单的,直接看官方文档就可以,无论支付宝支付还是微信支付,客户端的工作量要小于服务端

    有同步回调结果和异步回调结果,一般官方建议以异步回调结果为准,所以我们在同步回调结果判断支付成功后,去请求服务端异步回调。

    在微信支付对接时,遇到了同步回调都不回调的问题,按照上述官方文档所说。

    需要自己建相同的包名和类名,即WXPayEntrrActivity所在包名应为:

    但尝试之后,发现并不能进入回调方法,也许是官方文档说明不准确的原因,也许是自己理解的原因,我们需要在wxapi包下新建WXPayEntryActivity类接收回调方法,但包名并不是net.sourcefogr.simcpux,而是你自己项目的包名,比如gradle中你的appid为com.test,那么你的WXPayEntryActivity就应是com.test.wxapi.WXPayEntryActivity,同时记得在该Activity配置文件中添加

    ...
    android:exported="true"
    android:launchMode="singleTop" >

    欢迎关注技术公众号,微信号搜索ColorfulCode 代码男人

    分享技术文章,投稿分享,不限技术种类,不限技术深度,让更多人因为分享而受益。

     

    展开全文
  • 问题我所遇到的需求是APP里有两处涉及到微信支付,订单支付和充值支付,且支付完成后需要通知后台做其他操作(后台收到的支付结果通知是异步的,服务器是被动的),而微信支付的结果回调都在一个WXP...

    在集成微信支付时才发现微信的开发文档果然有些坑,本文主要是记录我在区分微信支付回调问题的处理。也让遇到同样问题的小伙伴们找到处理方法。若您知道此问题的解决办法,请不要喷我,您可以选择点击关闭此浏览器标签,谢谢。

    问题

    我所遇到的需求是APP里有两处涉及到微信支付,订单支付和充值支付,且支付完成后需要通知后台做其他操作(后台收到的支付结果通知是异步的,服务器是被动的),而微信支付的结果回调都在一个WXPayEntryActivity里面,而且此类微信官方规定的。我想要区分我的支付结果是属于订单支付还是充值支付,以便做出相应的操作,该怎么办呢?

    思路

    刚开始有些懵逼,毕竟不熟悉微信支付。所以最开始选择了用一个全局变量来保存当前的操作类型值,收到支付回调后判断此类型值,做出不同的操作。但总觉得这样做有些不妥。又想想微信这样的设计肯定不是没有考虑到这方面啊,所以就在调用微信支付SDK的地方来找方法。果不其然在PayReq里找到了这样一个方法:

    9784a0ade8da?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    调起微信支付SDK的地方

    光找到传入数据的地方还不行,所有又去了回调页面WXPayEntryActivity里找接收数据的地方:

    9784a0ade8da?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    WXPayEntryActivity

    阿西吧!居然没有关于接收数据的方法...

    又把PayResp拿来试试,果然功夫不负有心人:

    PayResp resp = (PayResp) baseResp;

    String payType = resp.extData;

    那这样一来就好办了呀,我就说嘛,微信这样设计肯定是考虑了这个问题的。

    代码

    还是把具体代码贴一下吧

    1.生成加密串。

    加密操作放在后台的,所以只需要传入相应的标题、本地订单号、价格给后台,后台会返给我调用微信支付SDK的相应参数,这里要注意一下,传给后台的价格必须是乘以100,比如支付价格为1元,那就得传100给后台,当然后台做处理也是可以的,还有价格不能为0,包括支付宝也是一样的。收到后台的数据如下:

    {

    "msg": 1,

    "data": {

    "appid": "wxf6a28d9fa0e4a5e7",

    "partnerid": "1482680562",

    "prepayid": "wx201711161536297ca36c8ab20902031739",

    "package": "Sign=WXPay",

    "noncestr": "cd98f00b204e9800998ecf8427e",

    "timestamp": 1510817789,

    "sign": "D1262473FD0AFD56E24E59248756666D"

    },

    }

    2.调起微信支付。

    这里是将后台返回的数据都装在了一个JavaBean里面

    public void wxPay(WxPayStringBean.DataBean bean) {

    PayReq request = new PayReq();

    IWXAPI api = mModel.wxPay();

    api.registerApp(Constants.KEY.WeChat.APP_ID);

    request.appId = bean.getAppid();

    request.partnerId = bean.getPartnerid();

    request.prepayId = bean.getPrepayid();

    request.packageValue = bean.getPackageX();

    request.nonceStr = bean.getNoncestr();

    request.timeStamp = bean.getTimestamp() + "";

    //传入一个标识,以便区分回调

    request.extData = "RechargePay";

    request.sign = bean.getSign();

    api.sendReq(request);

    }

    @Data

    public class WxPayStringBean {

    private int msg;

    private String error;

    private DataBean data;

    private int hc;

    @Data

    public static class DataBean {

    private String appid;

    private String partnerid;

    private String prepayid;

    @SerializedName("package")

    private String packageX;

    private String noncestr;

    private int timestamp;

    private String sign;

    }

    }

    在上门的wxPay方法中,可以看到传入一个参数

    request.extData = "RechargePay";

    3.在收到支付回调的页面做判断

    @Override

    public void onResp(BaseResp baseResp) {

    PayResp resp = (PayResp) baseResp;

    String payType = resp.extData;

    switch (payType) {

    case "OrderPay": //订单支付的回调

    // TODO: doSomething

    break;

    case "RechargePay": //充值支付的回调

    // TODO: doSomething

    break;

    }

    }

    End

    展开全文
  • 一般支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。 对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知...

    一般支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。

    对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。 (通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)
    废话不多说 (先理下思路)  下面以生产消费者 模式  进行梳理

    1.TTL:存活时间
    2.死信:过了存活期的消息
    3.Dead Letter Exchange:"死信" 交换器  其实就是普通的交换器而已.Exchange有4个类型:direct,topic,fanout,header
    4.routingkey:消费者队列绑定到交换机时要指定路由key (详细请看:
    rabbitmq-----Routing和topic模式)

    1.首先  在Connection中创建一个Channel,通过Channel声明两个交换器,一个是 用来接收通知数据的交换器ExchangeA,一个是延时通知数据的交换器ExchangeB。

    2.声明两个队列,一个"死信"队列queueA,一个延时通知数据队列queueB。

    3.然后,交换器ExchangeA和 "死信"队列queueA  绑定,把延时通知数据的交换器ExchangeB和queueB进行绑定。交换器再和队列进行绑定时会设置routingkey

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:rabbit="http://www.springframework.org/schema/rabbit"
           xsi:schemaLocation="
              http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/rabbit
              http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
    
    
        <!--配置connection-factory,指定连接rabbit server参数 -->
        <rabbit:connection-factory id="connectionFactory" virtual-host="/" username="${USERNAME}" password="${PASSWORD}" host="${HOST}" port="${PORT}"/>
    
        <!--定义rabbit模版,指定连接工厂以及定义exchange-->
        <rabbit:template id="amqpTemplate" connection-factory="connectionFactory" />
    
        <!--MQ的管理,包括队列,交换器,声明等-->
        <rabbit:admin connection-factory="connectionFactory" />
    
    
    <!--定义一个交换机exchangeA,路由类型为direct,所有的订单会塞给此交换机 和 然后和queueA 绑定 key testQueue-->
     <rabbit:direct-exchange name="exchangeA" delayed="false"  id="exchangeA" durable="false" auto-delete="false">
         <rabbit:bindings>
             <rabbit:binding queue="queueA" key="testQueue"/>
         </rabbit:bindings>
    </rabbit:direct-exchange>
    <!--定义一个延时交换机,路由类型为direct,延时的数据会塞给此交换机 并和exchangeB绑定-->
    <rabbit:direct-exchange name="exchangeB"  id="exchangeB" delayed="false" durable="false" auto-delete="false">
            <rabbit:bindings>
                <rabbit:binding queue="queueB" key="testQueue"/>
            </rabbit:bindings>
    </rabbit:direct-exchange>
    
    <!--定义队列,queueA-->
    <rabbit:queue name="queueA" durable="false"/>
    
    <!--定义延时队列,queueB-->
    <rabbit:queue name="queueB" durable="false">
          <rabbit:queue-arguments>
                <!--  队列绑定参数 告诉rabbit 将超时的数据推送到 死信交换机-->
                <entry key="x-dead-letter-exchange" value="exchangeA" />
                <entry key="x-dead-letter-routing-key" value="testQueue" />
          </rabbit:queue-arguments>
    </rabbit:queue>
            
        
    
    <!--队列监听-->
    <rabbit:listener-container connection-factory="connectionFactory">
        <rabbit:listener ref="myCustomer" method="listen" queue-names="queueA" />
        <rabbit:listener ref="myCustomer" method="listen" queue-names="queueA" />
        <rabbit:listener ref="myCustomer" method="listen" queue-names="queueA" />
    </rabbit:listener-container>
    
    <!--定义消费者-->
    <bean id="myCustomer" class="xxx.RabbitCustomer" />

    4.创建生产者类(下面贴出部分代码 具体按自己需求实现) RabbitService

    public static void publish(String queue, String message, long delay) {
            try {
                Channel channel = connection.createChannel();//创建一个channel,不管是生产数据,还是消费数据,都是通过channel去操作的
                AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
                    builder.contentType("text/plain");
                if(delay ==0){
                    AMQP.BasicProperties properties = builder.build();
                    //如果延时为0 走死信交换器
                    channel.basicPublish("exchangeA",
                                        "testQueue",
                                        properties,
                                        message.getBytes()
                    );
                }else{
                    //否则推送到延时交换器
                    builder.deliveryMode(2);//设置消息持久化
                    builder.expiration(String.valueOf(delay*1000)); //设置延时时间  rabbitmq  是毫秒
                    AMQP.BasicProperties properties = builder.build();
                    channel.basicPublish("exchangeB","testQueue", properties, message.getBytes());
                }
    
                channel.close();
            } catch (Exception e) {
                logger.error("rabbit-publish-error:{}", e.getMessage());
            }
        }

    5.创建消费者类  RabbitCustomer(下面部分代码)

    //message 为json数据
    public void listen(String message) {
            try {
                JSONObject jsonData;
                Integer pushNum;
                try {
                    jsonData= loadMessage(message);
                    pushNum= paras.getInteger("pushNum");
                } catch (Exception e) {
                    logger.error("异步通知错误:", e.getMessage());
                    return;
                }
                String result = null;
                try {
                      result = doHttpNotify(jsonData, connectionsPoolExecutor);
                } catch (Exception e) {
                    logger.error("异步通知错误:"+e.getMessage());
                }
                logger.info("异步通知返回:" + result);
    
                if (StringUtils.isNotBlank(result) && result.length() >= 60) {
                    result = result.substring(0, 60);
                }
                
                if (StringUtils.isNotBlank(result) && "success".equals(result.trim())) {
                        //返回成功的逻辑
                } else {
                    //处理失败的逻辑 然后准备 重新发起通知
                   paras.put("pushNum", pushNum+ 1);
                   if (retry == 0) {
                        RabbitService.publish(jsonData.toJSONString(), 5);  //5s
                    } else if (retry == 1) {
                        RabbitService.publish(jsonData.toJSONString(), 30);  //30s
                    } else if (retry == 2) {
                        RabbitService.publish( jsonData.toJSONString(), 120); //120s
                    } else {
                        logger.error("异步通知失败");
                    }
                }
            } catch (Exception e) {
                logger.error("异步通知失败" + e.getMessage());
            } finally {
                
            }

     

    展开全文
  • /** * 支付成功后的微信支付异步通知 */ @RequestMapping(value="/wxpay") public void wxpay(HttpServletRequest request, ... // 获取微信支付结果 PayResult payResult = wxOrderService.getWxPayResult(reque.
    /**
     * 支付成功后的微信支付异步通知
     */
    @RequestMapping(value="/wxpay")
    public void wxpay(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    	log.info("支付成功后的微信支付异步通知");
    
    	// 获取微信支付结果
    	PayResult payResult = wxOrderService.getWxPayResult(request.getInputStream());
    
    	boolean isPaid = payResult.getReturn_code().equals("SUCCESS") ? true : false;
    	// 查询该笔订单在微信那边是否成功支付
    	// 支付成功,商户处理后同步返回给微信参数
    	PrintWriter writer = response.getWriter();
    	if (isPaid) {
    
    		String merchantOrderId = payResult.getOut_trade_no();			// 商户订单号
    		String wxFlowId = payResult.getTransaction_id();
    		Integer paidAmount = payResult.getTotal_fee();
    
    //			System.out.println("================================= 支付成功 =================================");
    
    		// ====================== 操作商户自己的业务,比如修改订单状态等 start ==========================
    		String merchantReturnUrl = paymentOrderService.updateOrderPaid(merchantOrderId, paidAmount);
    		// ============================================ 业务结束, end ==================================
    
    		log.info("************* 支付成功(微信支付异步通知) - 时间: {} *************", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
    		log.info("* 商户订单号: {}", merchantOrderId);
    		log.info("* 微信订单号: {}", wxFlowId);
    		log.info("* 实际支付金额: {}", paidAmount);
    		log.info("*****************************************************************************");
    
    
    		// 通知天天吃货服务端订单已支付
    //			String url = "http://192.168.1.2:8088/orders/notifyMerchantOrderPaid";
    
    		MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<>();
    		requestEntity.add("merchantOrderId", merchantOrderId);
    		String httpStatus = restTemplate.postForObject(merchantReturnUrl, requestEntity, String.class);
    		log.info("*** 通知天天吃货后返回的状态码 httpStatus: {} ***", httpStatus);
    
    		// 通知微信已经收到消息,不要再给我发消息了,否则微信会10连击调用本接口
    		String noticeStr = setXML("SUCCESS", "");
    		writer.write(noticeStr);
    		writer.flush();
    
    	} else {
    		System.out.println("================================= 支付失败 =================================");
    
    		// 支付失败
    		String noticeStr = setXML("FAIL", "");
    		writer.write(noticeStr);
    		writer.flush();
    	}
    
    }
    
    /**
     * @Description: 支付结果封装类
     */
    public class PayResult {
    	private String return_code;				// 返回状态码
    	private String appid;					// 公众账号ID
    	private String mch_id;					// 商户号
    	private String nonce_str;				// 随机字符串
    	private String sign;					// 签名
    	private String result_code;				// 业务结果
    	private String openid;					// 用户标识
    	private String trade_type;				// 交易类型
    	private String bank_type;				// 付款银行
    	private int total_fee;					// 总金额
    	private int cash_fee;					// 现金支付金额
    	private String transaction_id;			// 微信支付订单号
    	private String out_trade_no;			// 商户订单号
    	private String time_end;				// 支付完成时间
    	private String return_msg;				// 返回信息
    	private String device_info;				// 设备号
    	private String err_code;				// 错误代码
    	private String err_code_des;			// 错误代码描述
    	private String is_subscribe;			// 是否关注公众账号
    	private String fee_type;				// 货币种类
    	private String cash_fee_type;			// 现金支付货币类型
    	private String coupon_fee;				// 代金券或立减优惠金额
    	private String coupon_count;			// 代金券或立减优惠使用数量
    	private String coupon_id_$n;			// 代金券或立减优惠ID
    	private String coupon_fee_$n;			// 单个代金券或立减优惠支付金额
    	private String attach;					// 商家数据包
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public String updateOrderPaid(String merchantOrderId, Integer paidAmount) {
    
    	Example example = new Example(Orders.class);
    	Example.Criteria criteria = example.createCriteria();
    	criteria.andEqualTo("merchantOrderId", merchantOrderId);
    
    	Orders paidOrder = new Orders();
    	paidOrder.setPayStatus(PaymentStatus.PAID.type);
    	paidOrder.setAmount(paidAmount);
    
    	int result = ordersMapper.updateByExampleSelective(paidOrder, example);
    
    	return queryMerchantReturnUrl(merchantOrderId);
    }
    
    /**
     * @Description: 支付中心的支付状态 10:未支付 20:已支付 30:支付失败 40:已退款
     */
    public enum PaymentStatus {
    
    	WAIT_PAY(10, "未支付"),
    	PAID(20, "已支付"),
    	PAY_FAILED(30, "支付失败"),
    	SUCCESS(40, "已退款");
    
    	public final Integer type;
    	public final String value;
    
    	PaymentStatus(Integer type, String value){
    		this.type = type;
    		this.value = value;
    	}
    
    }
    @PostMapping("notifyMerchantOrderPaid")
    public Integer notifyMerchantOrderPaid(String merchantOrderId) {
    	orderService.updateOrderStatus(merchantOrderId, OrderStatusEnum.WAIT_DELIVER.type);
    	return HttpStatus.OK.value();
    }
    

     

    展开全文
  • 微信支付-支付结果通知接收

    万次阅读 多人点赞 2017-06-22 14:18:43
    微信支付-支付结果通知接收最近在做微信支付功能在微信成功后,微信通过异步方式返回支付结果是遇到了问题:参数接收不到。后来通过查阅资料才将问题解决,现在将解决方法分享一下。官方文档解释如上图所示:通过...
  • 微信支付回调

    2020-06-10 16:02:16
    2.微信支付回调是本地服务提供接口,微信调用本地服务的接口,我们接收微信传过来的支付结果。 3.注意事项,微信访问我们是以xml格式,这里我多微信传过来的xml格式转为map,然后进入service层进行处理 xml转map...
  • 用户扫码支付成功,微信异步回调商户 上一篇博客完成用户扫码支付功能: https://www.cnblogs.com/qdhxhz/p/9708534.html 当用户扫码支付成功之后,微信异步回调商户接口,告知用户支付成功。好让商户进行下一步...
  • 这两天优化了一下支付宝支付和微信支付订单回调的问题,之前我们的订单都是用手动回调给服务器,现在改成支付宝和微信原生的异步回调结果并没有像我们想象的那么简单,支付宝是很顺利的解决回调,用一般的方式接收...
  • 在集成微信支付时才发现...我所遇到的需求是APP里有两处涉及到微信支付,订单支付和充值支付,且支付完成后需要通知后台做其他操作(后台收到的支付结果通知是异步的,服务器是被动的),而微信支付的结果回调都在一...
  • 在用户支付完过后微信会调用我们给它的异步通知地址返回支付结果,需要注意的是我们给的通知地址是可以进行外网访问的 我使用的一些工具类方法大多是从官方给的demo,下面是下载地址 ...好了上代码 ...
  • PHP处理微信支付回调

    2018-05-18 14:20:00
    我们已经知道,微信无论是微信内置JSAPI支付、H5外部浏览器支付、扫码支付,都需要通过异步回调接收支付结果。 本文简介如何获取微信支付通知。 仅需要一个在之前设置好的回调地址的方法里写上如下: //处理...
  • 用户在微信公众号里面付款,输入支付密码后会弹出一... ... ... ...在微信支付的过程中,有这么一个流程:用户输入密码,微信验证后会异步通知商户支付结果。 发送通知的地址是之前在统一下单时,配置支付参数的notify...
  • 微信无论是微信内置JSAPI支付、H5外部浏览器支付、扫码支付,都需要通过异步回调接收支付结果。 本文简介如何获取微信支付通知。 仅需要一个在之前设置好的回调地址的方法里写上如下: //处理微信支付回调 ...
  • 微信JSAPI支付回调

    2017-01-25 18:18:00
    在经历了千幸万苦之,填完了所有的JSAPI支付的坑后(微信JSAPI支付 跟 所遇到的那些坑),好不容易调起了微信支付接口,看到了亲爱的支付页面,支付成功后发现自己还有个叫做微信回调的忘了处理,内心一万只草泥马在...
  • 浅析微信支付支付结果通知

    千次阅读 2018-11-06 17:40:10
    本文是【浅析微信支付】系列文章的第六篇,主要讲解支付成功...前面一章已经讲了如何调用统一下单接口和调起微信支付窗口,在调用下单接口时,我们会传入 异步接收微信支付结果通知的回调地址,顾名思义这个地址作用...
  • 微信无论是微信内置JSAPI支付、H5外部浏览器支付、扫码支付,都需要通过异步回调接收支付结果。 本文简介如何获取微信支付通知。 仅需要一个在之前设置好的回调地址的方法里写上如下: //处理微信支付回调 ...
  • (10)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。** 为何没有看到对订单状态更新的逻辑代码呢?为什么又调用了一次统一下单...
  • 商户系统和微信支付系统主要交互: 1、小程序内调用登录接口,获取到用户的openid,api参见公共api【小程序登录API】 2、商户server调用支付统一下单,api参见公共api【统一下单API】 3、商户server调用再次签名,...
  • 开发前配置进行代码接入前,需在微信后台填写授权回调域名,此域名必须经过ICP备案开发主要流程用户下单时选择微信支付商户进行业务逻辑处理并调用微信统一下单接口,微信H5交易类型为:trade_type=MWEB调用下单接口...
  • 开发前配置进行代码接入前,需在微信后台填写授权回调域名,此域名必须经过icp备案开发主要流程用户下单时选择微信支付商户进行业务逻辑处理并调用微信统一下单接口,微信h5交易类型为:trade_type=mweb调用下单接口...
  • 微信支付流程,统一下单接口https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1,其中需要参数【通知地址notify_url】异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数...
  • 前言 微信支付是由微信及财付通联合推出的移动支付创新产品。如今,随着微信支付的全面开放,相关需求也越来越多,很多开发人员进行... 4、异步通知商户支付结果回调)  一、生成商户订单与调用统一下单 API 这对
  • 框架使用的是spring boot我们集成微信支付 也就需要提供两个接口出来.一个是给前端 作用是拿到请求参数加签请求统一下单接口,得到预支付...异步通知我们支付结果好了.废话不哆嗦,直接上代码:@RestController@Request...
  • 微信支付V3.x版本实例(下)

    千次阅读 2015-01-31 19:07:00
    微信支付实现过程步骤:网页内支付场景---JS API 1.获取微信支付配置参数;微信支付参数需要的有3个:a....7.支付成功后微信异步回调填写的支付通知地址,并跳转到商户网页8.查询订单支付状态返回支付订单信息

空空如也

空空如也

1 2 3 4 5
收藏数 90
精华内容 36
关键字:

微信支付结果异步回调