针对APP的后台支付代码(微信和支付宝)

APP支付:

1.微信支付:

这是app支付时,一个完整的流程

1.1首先要去微信开放平台注册,并创建APP

1.2取得微信支付的权限

1.3 商户平台有公众号平台和APP平台两种,一定要是APP平台,可以在下面这个地方查看

1.4 我们需要在商户平台和开放平台上获取到以下数据:

开放平台:

APPID、APP_SECRET:见1图。

商户平台:

秘钥(APP_KEY):微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

商户号(MCH_ID):微信商户平台(pay.weixin.qq.com)-->账户设置-->商户信息-->微信支付商户号

数字证书(微信退款需要使用):微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->证书下载

2.支付宝的操作流程简单,文档清楚(略)

3准备工作结束,我的产品是使用Hbuilder开发的HTML5的APP,后端是依托于Java Web程序。工作流程参照时序图。主要代码如下,详情见文件

  其中用到一些工具方法  或者客户端创建代码都在链接里面有,我放在了码云上面 https://gitee.com/muziTM/payDemo

  3.1  入口

  

/**
 * 支付类   包含支付宝和微信
 * @author Tianming_Li
 *
 */
@Controller
@RequestMapping("/payController")
public class PayController {
    //订单
    @Autowired
    OrdersService orderService;
    //付费
    @Autowired
    PayService payService;
    //退费
    @Autowired
    RefundService refundService;
    //支付成功回调
    @Autowired
    CallBackService callBackService;
    /**
     * 下单
     * @param outTradeNo
     * @param payType
     * @param request
     * @param response
     * @param modelMap
     * @return
     */
    @RequestMapping("/pay")
    public String pay(@RequestParam(name="outTradeNo") String outTradeNo,@RequestParam(name="payType") String payType,
            HttpServletRequest request,HttpServletResponse response,
            ModelMap modelMap){
        //根据订单号获取到订单信息
        Orders order = orderService.selectOrdersInfoByOutTradeNo(outTradeNo);
        if("wxpay".equals(payType)){
            return payService.wxPay(order, request, response, modelMap);
        }else{
            return payService.aliPay(order);
        }
    }
    /**
     * 退款
     * @param outTradeNo
     * @param payType
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/refunds")
    public String refunds(@RequestParam(name="outTradeNo") String outTradeNo,@RequestParam(name="payType") String payType,
            HttpServletRequest request,HttpServletResponse response){
        //根据订单号获取到订单信息
        Orders order = orderService.selectOrdersInfoByOutTradeNo(outTradeNo);
        if("wxpay".equals(payType)){
            return refundService.wxRefund(order, request, response);
        }else{
            return refundService.aliRefund(order);
        }
    }

    /**
     * 接收微信支付成功通知
     *
     * @param request
     * @param response
     * @throws IOException
     */

    @RequestMapping(value = "/getWxPayNotify")
    public void getWxPayNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        callBackService.wxCallBack(request, response);
    }
    /**
     * 接收支付宝支付成功回调
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping("/getAliPayNotify")
    public void getAliPayNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        callBackService.aliCallBack(request, response);
    }

}

  3.2 支付代码

 

/**
 * 支付处理
 * @author Tianming_Li
 *
 */
@Service("payService")
public class PayServiceImpl implements PayService {

    protected static final Log logger = LogFactory.getLog(PayServiceImpl.class);

    @Override
    public String wxPay(Orders order, HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
        BaseDao dao = DaoUtils.getDao("sys");
        StringBuilder sb = new StringBuilder();
        sb.append("SELECT * FROM WX_PAY_CONFIG WHERE YY_ID = ‘");
        sb.append(order.getYyId());
        sb.append("‘");
        //获取到微信配置参数
        WxPayConfig appPayConfig = dao.getObjectBySql(sb.toString(), WxPayConfig.class);
        Map<String, Object> map = new HashMap<String, Object>();
        //初始化一个请求对象
        WxRequestHandler wxRequestHandler = new WxRequestHandler(request, response);
        String payFee = order.getPayMoney();
        int intPayFee = (int) (Float.valueOf(payFee) * 100);
        String nonceStr = WxUtils.getNonceStr();
        String outTradeNo = order.getOutTradeNo();
        String timestamp = WxUtils.getTimeStamp();
        wxRequestHandler.setParameter("appid", appPayConfig.getAppId());//appId
        wxRequestHandler.setParameter("mch_id", appPayConfig.getMchId());//商户号
        wxRequestHandler.setParameter("nonce_str", nonceStr);//随机字符串
        wxRequestHandler.setParameter("body", appPayConfig.getBody());//商品描述
        wxRequestHandler.setParameter("notify_url", appPayConfig.getNotifyUrl());//通知地址
        wxRequestHandler.setParameter("out_trade_no", outTradeNo);
        wxRequestHandler.setParameter("spbill_create_ip", request.getRemoteAddr());
        wxRequestHandler.setParameter("total_fee", String.valueOf(intPayFee));
        wxRequestHandler.setParameter("trade_type", "APP");
         //注意签名生成方式,具体见官方文档
        wxRequestHandler.setParameter("sign", wxRequestHandler.createMD5Sign(appPayConfig.getAppKey()));
        String prepayid;
        try {
            prepayid = wxRequestHandler.sendPrepay();
            if (prepayid != null && !prepayid.equals("")) {
                String signs ="appid=" + appPayConfig.getAppId()
                            + "&noncestr=" + nonceStr
                            + "&package=Sign=WXPay"
                            + "&partnerid="+ appPayConfig.getPartnerId() //商户id
                            + "&prepayid=" + prepayid
                            + "&timestamp=" + timestamp
                            + "&key=" + appPayConfig.getAppKey();//商户平台---api安全---密钥
                map.put("code", 200);
                map.put("info", "success");
                map.put("prepayid", prepayid);
                map.put("sign", WxUtils.getMD5Encode(signs, "utf8").toUpperCase());
                map.put("appid", appPayConfig.getAppId());
                map.put("timestamp", timestamp); // 等于请求prepayId时的time_start
                map.put("noncestr", nonceStr); // 与请求prepayId时值一致
                map.put("package", "Sign=WXPay"); // 固定常量
                map.put("partnerid", appPayConfig.getPartnerId());//商户id
            } else {
                map.put("code", 400);
                map.put("info", "获取prepayid失败");
            }
        } catch (Exception e) {
            map.put("code", 405);
            map.put("info", "系统异常");
        }

        return JSONUtils.toJSON(map);
    }

    @Override
    public String aliPay(Orders order) {
        //获取配置参数
        BaseDao dao = DaoUtils.getDao("sys");
        StringBuilder sb = new StringBuilder();
        sb.append("SELECT * FROM ALI_PAY_CONFIG WHERE YY_ID = ‘");
        sb.append(order.getYyId());
        sb.append("‘");
        AliPayConfig appPayConfig = dao.getObjectBySql(sb.toString(), AliPayConfig.class);

        // 实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型),为了取得预付订单信息
        AlipayClient alipayClient = new DefaultAlipayClient(appPayConfig.getUrl(), appPayConfig.getAppId(),
                appPayConfig.getRsaPrivateKey(), appPayConfig.getFormat(), appPayConfig.getCharset(),
                appPayConfig.getPublicKey(), appPayConfig.getSigntype());
        // 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        // SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        //销售产品码,商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAY
        BeanUtils.copy(order, model);//将订单信息复制到model类中
        request.setBizModel(model);
        // 回调地址  指向回调函数  example: https://ip:port/payController/getAliPayNotify.do
        request.setNotifyUrl(appPayConfig.getNotifyUrl());
        String orderStr = "";
        try {
            // 这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            orderStr = response.getBody();
            logger.info("订单str:" + orderStr);
        } catch (AlipayApiException e) {
            logger.info(e.getMessage());
        }
        return orderStr;
    }

}

3.2回调代码

@Service("callBackService")
public class CallBackServiceImpl implements CallBackService {

    private static final Log LOGGER = LogFactory.getLog(CallBackServiceImpl.class);

    public static final String SUCCESS = "SUCCESS";

    @SuppressWarnings("unchecked")
    @Override
    public void wxCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        InputStream inputstream = request.getInputStream();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int len = 0;
        while((len = inputstream.read(b))!= -1){
            outputStream.write(b, 0, len);
        }
        String result = new String(outputStream.toByteArray(), "utf-8");
        inputstream.close();
        outputStream.close();
        Map<String, String> map = null;
        //解析微信通知返回的信息
        try {
            map = WxUtils.doXMLParse(result);
        } catch (JDOMException e) {
            LOGGER.info("微信回调失败:"+e.getMessage());
        }
        // 若支付成功,则告知微信服务器收到通知
        if (SUCCESS.equals(map.get("return_code")) && SUCCESS.equals(map.get("result_code"))) {

            /**
             * ...
             * 回调业务
             */

            //微信会一直调用接口,直到我们返回SUCCESS
            String notifyStr = WxUtils.setXML(SUCCESS, "");
            writer.write(notifyStr);
            writer.flush();
        }
    }

    @Override
    public void aliCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
        LOGGER.info("进入支付宝回调");
        // 获取支付宝GET过来反馈信息
        String reqWay = "";
        if ("GET".equals(request.getMethod())) {
            reqWay = "GET";
        }
        Map<String, String> params = new HashMap<String, String>();
        Map<?, ?> requestParams = request.getParameterMap();
        for (Iterator<?> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            if ("GET".equals(reqWay)) {
                try {
                    valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                } catch (UnsupportedEncodingException e) {
                    LOGGER.info("不支持的编码:" + e.getMessage());
                }
            }
            params.put(name, valueStr);
        }
        String tradeNo = request.getParameter("trade_no"); // 支付宝交易号
        String tradeStatus = request.getParameter("trade_status"); // 支付状态
        String outTradeNo = request.getParameter("out_trade_no"); // 系统订单号
        String sellerId = request.getParameter("seller_id"); // 商户号

        LOGGER.info("支付宝交易号:" + tradeNo + ", 返回状态:" + tradeStatus + ",订单号  :" + outTradeNo);
        Map<String, Object> map = new HashMap<String, Object>();
        String result = "";
        try {
            if ("TRADE_SUCCESS".equals(tradeStatus)) {
                /**
                 * ...
                 * 回调业务
                 */
            } else {
                result = "fail";// 为了保证不重复回调
            }
        } catch (Exception e) {
            result = "fail";
        }
        map.put(result, result);
        AliUtils.renderText(response, result);

    }

}

3.4 微信退费的时候需要证书,密码默认是商户号,由于项目中使用了多个微信商户号,因此有多个证书,路径和密码放在了数据库中

public class WxRequestHandler{
/**
     * 退费
     * @return
     */
    public Map<String,String> sendWxChanel(String filePath,String pwd) throws Exception{
        Map<String,String> map =null;
        Set es=this.getAllParameters().entrySet();
        Iterator it=es.iterator();
        StringBuilder sb = new StringBuilder("<xml>");
        while(it.hasNext()){
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            sb.append("<"+k+">"+v+"</"+k+">");
        }
        sb.append("</xml>");
        String params=sb.substring(0);
        String requestUrl = this.getGateUrl();
        TenpayHttpClient httpClient = new TenpayHttpClient();
        httpClient.setReqContent(requestUrl);
        String resContent = "";
        //filepath 文件路径 pwd 密码
        if (httpClient.callHttpPost(requestUrl, params,true,filePath,pwd)) {
            resContent = httpClient.getResContent();
            map=WxUtils.doXMLParse(resContent);
        }
        return map;
    }

}

原文地址:https://www.cnblogs.com/LLLLitm/p/9951597.html

时间: 2024-11-08 17:29:16

针对APP的后台支付代码(微信和支付宝)的相关文章

支付接口 - 微信,支付宝

在hbuider下的app 调用支付接口 支付宝功能申请 登录支付宝账号,签约申请“移动快捷支付”功能,操作流程参考:支付宝帮助中心 获取PID,参考教程:获取合作者身份ID 生成密钥(公钥和私钥),并提交到支付宝,参考教程:生成RSA密钥上传公钥 服务器生成订单示例(PHP)参考开源示例代码github-支付宝C#生成支付宝订单示例 微信支付功能申请 使用微信支付功能需到微信开放平台申请移动应用并开通支付功能微信APP支付接入商户服务中心申请应用后可以获取AppID和AppSecret值. 开

抢鲜看:微信、支付宝、高德地图在Apple Watch上是酱紫玩啊!

3月9日凌晨消息,苹果公司2015年春季发布会在美国旧金山芳草地艺术中心召开.伴随首次亮相的Apple Watch还有其首批定制的APP,国内知名应用微信.支付宝均上榜. 本次发布会对Apple Watch进行了真机演示.演示中展示了多个Apple Watch应用,包括微信.支付宝,微博-- 而3月13日(本周五)苹果地图的中国合作商高德公司将在北京召开发布会,今日据高德论坛曝光的Apple Watch展示图判断,本次高德发布产品或与Apple Watch相关. 下面一起看看首批亮相Apple

[转]微信小程序 c#后台支付结果回调

本文转自:http://www.cnblogs.com/weizhiing/p/7700723.html 又为大家带来简单的c#后台支付结果回调方法,首先还是要去微信官网下载模板(WxPayAPI),将模板(WxPayAPI)添加到服务器上,然后在打开WxPayAPI项目中的example文件下的 NativeNotifyPage.aspx打开网页中的代码页如图: 将以下代码加入进去就能完成: public partial class NativeNotifyPage : System.Web.

微信支付PHP SDK —— 公众号支付代码详解

在微信支付 开发者文档页面 下载最新的 php SDK http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 这里假设你已经申请完微信支付 1. 微信后台配置  如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请求的哪个文件所在的目录. 例如jsapi 发起请求一般是jsapi.php所在目录 为测试目录,测试白名单即开发人员的微信号. 正式的支付授权目录不能和测试的一样否则会报错.不填

PHP后台支付的开发:微信支付和支付宝支付

关于支付的流程之类的就不做解释,大家可以自行搜索! 微信支付 项目前提:本人用的是tp框架,PHP语言下载到微信平台提供的微信支付接口文件,放在了tp第三方类库vendor,命名为WxpayAPI, WxpayAPI/lib/WxPay.Api.php 接口访问类; WxpayAPI/lib/WxPay.Config.php 配置账号信息; WxpayAPI/lib/WxPay.Data.php 数据对象基础类; WxpayAPI/lib/WxPay.Exception.php 微信支付API异

MUI 微信 和支付宝支付 (前台代码)

<!-- 校园公告详情界面 用于显示校园公告的详情信息 在校园公告界面点击某一条目后 进入本界面查看详情 --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maxim

支付sdk —— 该组件为封装了 微信,支付宝,银联支付

[精品]  支付组件 简要说明该组件为封装了 微信,支付宝,银联支付, 一键快速集成,几行代码即可集成 微信,支付宝,银联支付. ## 示例: # 测试账号:1.银联支付:提供测试使用卡号.手机号信息(此类信息仅供测试,不会发生正式交易)招商银行借记卡:6226090000000048 手机号:18100000000 密码:111101 短信验证码:123456(先点获取验证码之后再输入) 证件类型:01身份证 证件号:510265790128303 姓名:张三 华夏银行贷记卡:62263880

微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付

一.首先先确定H5支付权限已经申请!(需要微信h5支付demo的可以加 851 488 243 备注:h5支付) 二.开发流程 1.用户在商户侧完成下单,使用微信支付进行支付 2.由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB 3.统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名"mweb_url"),商户通过mweb_url调起微信支付中间页 4.中间页进行H5权限的校验,安全性检查(此处常见错误请见下文) 5.如支付成

如何调通微信支付及微信发货通知接口(Js API)

微信支付提供了一个支付测试页面,微信支付正式使用需要测通支付.发货通知接口 .告警接口.维权接口.告警接口.维权接口非常简单.支付界面调通也相对简单,主要是发货通知接口稍微复杂一点.调通发货通知接口需要注意以下几点: (1) 微信支付文档中提到发货通知接口的PostData,这个其实不是一个form里的一项,其实 PostData的提法有点误导,理解为json串就可以了. (2)以下的写法是错误的: <form name="form2" target="_blank&q