朋也
朋也
  • 发布:2015-12-01 11:32
  • 更新:2015-12-01 11:32
  • 阅读:35132

微信、支付宝支付那点事

分类:MUI

公司要在MUI开发的APP里添加上支付功能,然后爬坑开始了。。

因为公司用的是Java语言开发的服务端,所以就要找Java版本的支付代码了
首先在dcloud的问答里搜索看有没有相关文章,找到了下面两篇有用的

第一篇是配置支付宝支付的,第二篇是我在下面发了一个回复求微信支付的代码(所以代码在回复里)

dcloud官方给的php代码地址:https://github.com/dcloudio/H5P.Server

下面说说我在爬坑的时候碰到的障碍

  1. Java语言输出方法有print(),println() 切记一定不能用println() 这个方法输出后会换行,所以一直是失败状态,我开发的时候是支付宝报的错ALI10
  2. 微信支付,从APP里请求到服务端接口,在接口里会调用一次微信的接口,此时涉及到一次签名(sign),切记在签名前发送给微信服务器的参数要按照a-z排列好,然后在去签名,完成之后请求微信支付接口,微信给返回一些XML数据,其中只有prepay_id有用,其他需要的参数基本上都是在微信的配置类里配置好了的,此时转换成的json格式数据写出的还有一次签名(sign),这个签名跟上面第一次的签名不一样,要记得在签名参数最后带上key
  3. 支付宝支付的参数,地址类的字符串比如:notify_url等,不需要URLEncoder.encode(),参数都要加上""
  4. xcode里,如果APP跳转到支付宝打开的是网页版的,而不是支付宝APP,就需要在xcode里配置plist文件添加下面这些代码
    <key>LSApplicationQueriesSchemes</key>  
    <array>  
    <string>weixin</string>  
    <string>wechat</string>  
    <string>alipay</string>  
    <string>sinaweibo</string>  
    <string>weibosdk</string>  
    <string>tencentweiboSdkv2</string>  
    <string>weibosdk2.5</string>  
    <string>mqq</string>  
    <string>mqqOpensdkSSoLogin</string>  
    <string>mqqopensdkapiV2</string>  
    <string>mqqwpa</string>  
    <string>mqqopensdkapiV3</string>  
    <string>wtloginmqq2</string>  
    </array>

下面是我Java服务端的代码,给大家分享一下
支付宝(使用了支付宝商户SDK)

public void alipayapi(HttpServletRequest request, HttpServletResponse response) throws Exception {  
    response.setContentType("text/plain; charset=UTF-8");  
    PrintWriter out = response.getWriter();  
    ////////////////////////////////////请求参数//////////////////////////////////////  

    //支付类型  
    String payment_type = "1";  
    //必填,不能修改  
    //服务器异步通知页面路径  
    String notify_url = ApplicationListener.getBasePath() + "pay/sdk/alipay/notify";  
    //需http://格式的完整路径,不能加?id=123这类自定义参数  

    //页面跳转同步通知页面路径  
//        String return_url = URLEncoder.encode(ApplicationListener.getBasePath() + "pay/wap/alipay/return");  
    //需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/  

    //商户订单号  
    String out_trade_no = request.getParameter("orderId");  
    //商户网站订单系统中唯一订单号,必填  

    //订单名称  
    String subject = "支付预定金";  
    //必填  

    //付款金额  
    String total_fee = request.getParameter("total_fee");  
    //必填  

    //商品展示地址  
    String show_url = ApplicationListener.getBasePath();  
    //必填,需以http://开头的完整路径,例如:http://www.商户网址.com/myorder.html  

    //订单描述  
    String body = "订单支付定金";  
    //选填  

    //超时时间  
    String it_b_pay = "1d";  
    //选填  

    //把请求参数打包成数组  
    Map<String, String> sParaTemp = new HashMap<String, String>();  
    sParaTemp.put("service", "mobile.securitypay.pay");  
    sParaTemp.put("partner", AlipayConfig.partner);  
    sParaTemp.put("seller_id", AlipayConfig.seller_id);  
    sParaTemp.put("_input_charset", AlipayConfig.input_charset);  
    sParaTemp.put("payment_type", payment_type);  
    sParaTemp.put("notify_url", notify_url);  
    sParaTemp.put("out_trade_no", out_trade_no);  
    sParaTemp.put("subject", subject);  
    sParaTemp.put("total_fee", total_fee);  
    sParaTemp.put("show_url", show_url);  
    sParaTemp.put("body", body);  
    sParaTemp.put("it_b_pay", it_b_pay);  
    String sHtmlText = "";  
    for(Iterator iter = sParaTemp.keySet().iterator(); iter.hasNext();) {  
        String name = (String) iter.next();  
        String value = sParaTemp.get(name);  
        sHtmlText += name + "=\"" + value + "\"&";  
    }  
    //建立请求  
    System.out.println(sHtmlText);  
    sHtmlText = sHtmlText.substring(0, sHtmlText.length()-1);  
    String sign = RSA.sign(sHtmlText, AlipayConfig.PRIVATE, AlipayConfig.input_charset);  
    String outText = sHtmlText + "&sign=\"" + URLEncoder.encode(sign, "UTF-8") + "\"&sign_type=\""+AlipayConfig.sign_type+"\"";  
    out.print(outText);  
}

微信支付(用到了微信Java版SDK,下载地址
RequestData.java

public class RequestData {  
    private String appid;  
    private String body;  
    private String mch_id;  
    private String nonce_str;  
    private String notify_url;  
    private String out_trade_no;  
    private String sign;  
    private String spbill_create_ip;  
    private String total_fee;  
    private String trade_type;  

    //getter,setter  
}
public void alipayapi(HttpServletRequest request, HttpServletResponse response) throws Exception {  
    response.setContentType("text/plain; charset=UTF-8");  
    PrintWriter out = response.getWriter();  

    //微信分配的公众账号ID(企业号corpid即为此appId)  
    String appid = Configure.getAppid();  
    //必填  

    //商品或支付单简要描述  
    String body = "预定金支付";  
    //必填  

    //微信支付分配的商户号  
    String mch_id = Configure.getMchid();  
    //必填  

    //随机字符串,不长于32位。推荐随机数生成算法  
    String nonce_str = RandomStringGenerator.getRandomStringByLength(32);  
    //必填  

    //接收微信支付异步通知回调地址  
    String notify_url = ApplicationListener.getBasePath() + "pay/sdk/wxpay/notify";  
    //必填  

    //商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号  
    String out_trade_no = request.getParameter("orderId");  
    //必填  

    //签名,详见签名生成算法  
    String sign = "";  
    //必填  

    //APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。  
    String spbill_create_ip = IpUtil.getIpAddr(request);  
    //必填  

    //订单总金额,单位为分,详见支付金额  
    Double total_fee_d = Double.parseDouble(request.getParameter("total_fee"));  
    Double total_fee_s = total_fee_d * 100;  
    String total_fee = total_fee_s.intValue() + "";  
    //必填  

    //取值如下:JSAPI,NATIVE,APP,详细说明见参数规定  
    String trade_type = request.getParameter("trade_type");  
    //必填  

    //=============================以下参数 非必填 ===============================  

    //商品名称明细列表  
    String detail = "";  
    //非必填  

    //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据  
    String attach = "";  
    //非必填  

    //符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型  
    String fee_type = "";  
    //非必填  

    //终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"  
    String device_info = "";  
    //非必填  

    //商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠  
    String goods_tag = "";  
    //非必填  

    //订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则  
    String time_start = "";  
    //非必填  

    //订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则  
    //注意:最短失效时间间隔必须大于5分钟  
    String time_expire = "";  
    //非必填  

    //trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。  
    String product_id = "";  
    //非必填  

    //no_credit--指定不能使用信用卡支付  
    String limit_pay = "";  
    //非必填  

    //trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。openid如何获取,可参考【获取openid】。  
    //企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换  
    String openid = "";  
    //非必填  

    RequestData reqData = new RequestData();  
    reqData.setAppid(appid);  
    reqData.setBody(body);  
    reqData.setMch_id(mch_id);  
    reqData.setNonce_str(nonce_str);  
    reqData.setNotify_url(notify_url);  
    reqData.setOut_trade_no(out_trade_no);  
    reqData.setSpbill_create_ip(spbill_create_ip);  
    reqData.setTotal_fee(total_fee);  
    reqData.setTrade_type(trade_type);  
    sign = Signature.getSign(reqData);  
    reqData.setSign(sign);  
    String result = new HttpsRequest().sendPost("https://api.mch.weixin.qq.com/pay/unifiedorder", reqData);  

    System.out.println(result);  

    Map map = XMLParser.getMapFromXML(result);  
    String prepay_id = (String) map.get("prepay_id");  
    System.out.println(prepay_id);  

    String timestamp = String.valueOf(System.currentTimeMillis() / 1000);  
    String s="appid="+appid+"&noncestr="+nonce_str+"&package=Sign=WXPay"+"&partnerid="+  
            mch_id+"&prepayid="+prepay_id+"&timestamp="+timestamp+"&key=" + Configure.getKey();  
    String newSign = MD5.MD5Encode(s).toUpperCase();  
    StringBuffer json = new StringBuffer();  
    json.append("{\"appid\":\"");  
    json.append(appid);  
    json.append("\",\"noncestr\":\"");  
    json.append(nonce_str);  
    json.append("\",\"package\":\"");  
    json.append("Sign=WXPay");  
    json.append("\",\"partnerid\":\"");  
    json.append(mch_id);  
    json.append("\",\"prepayid\":\"");  
    json.append(prepay_id);  
    json.append("\",\"timestamp\":\"");  
    json.append(timestamp);  
    json.append("\",\"sign\":\"");  
    json.append(newSign);  
    json.append("\"}");  
    System.out.println(json.toString());  
    out.print(json.toString());  
}
7 关注 分享
BoredApe wenju damdmen Nelson lianxia 8***@qq.com 1***@qq.com

要回复文章请先登录注册

1***@qq.com

1***@qq.com

你好!我这边后台的统一下单的参数跟上面的封装的有些不同,我是自己将参数ASCII排序,然后MD5加密,微信服务端返回xml也显示我成功了
<xml><return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx01ec1fe347a6e939]]></appid>
<mch_id><![CDATA[1480225992]]></mch_id>
<nonce_str><![CDATA[xitA7hV7kOk7XvXp]]></nonce_str>
<sign><![CDATA[7F60F5E43C42D0767BA2EDB3B4E53052]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx20171202113225c2a4e845430221678188]]></prepay_id>
<trade_type><![CDATA[MWEB]]></trade_type>
<mweb_url><![CDATA[https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20171202113225c2a4e845430221678188&package=4231263884]]></mweb_url>
</xml>
,剩余后面第二次签名然后返回到hbuilder的操作跟上面一样,可是报code: -100 message: "[payment微信:-1] General errors"错误
2017-12-02 11:42
1231312312312

1231312312312

回复 1231312312312 :
确定二次签名和之前签名使用的是同一种加密方式
2017-07-30 16:56
1231312312312

1231312312312

您好,我这边使用微信团队提供的封装包(https://github.com/wxpay/WXPay-SDK-Java)进行统一下单,能够获得prepay_id,但是再次签名得到sign后,还是报code: -100 message: "[payment微信:-1] General errors",还请多多指教哈,多谢多谢
2017-07-25 23:26
游帝2015

游帝2015

请问有关于c#服务器后台的支付通道代码吗?
2017-06-26 10:24
朋也

朋也 (作者)

回复 yungehaha :
官方有例子,在github上,你搜索一下
2017-03-13 23:00
yungehaha

yungehaha

大神,问下php后台该怎么写
2017-03-03 16:48
haolin

haolin

推荐一款轻量开源的支付宝组件:https://github.com/ihaolin/alipay
2016-10-24 18:53
笑一阵

笑一阵

忍不住哭出来 原来参数是要一个一个按照官方的来的。。。搞了一整天
2016-07-18 11:16
我不是汪小东

我不是汪小东

回复 9***@qq.com :
您好,请问您微信支付 返回错误-100 请问解决了嘛?
2016-07-11 15:48
9***@qq.com

9***@qq.com

回复 四月技术伍成才 :
你好,请问你这个问题解决了吗
2016-07-06 15:41