微信app支付(Java+android)

微信app支付(Java+android)

第一步 申请AppID 绑定商户号

1.创建移动应用

在微信开发平台https://open.weixin.qq.com/注册账号创建移动应用,填写相关信息,审核通过之后会得到AppID
在这里插入图片描述
点击查看
在这里插入图片描述

2.申请微信支付

申请微信商户与创建的移动应用绑定,成功之后如下图
在这里插入图片描述

第二步 导入依赖

在maven项目中的pom.xml中引入一下依赖

<dependency>
	<groupId>com.github.wxpay</groupId>
	<artifactId>wxpay-sdk</artifactId>
	<version>0.0.3</version>
</dependency>
<dependency>
    <groupId>com.egzosn</groupId>
    <artifactId>pay-java-common</artifactId>
    <version>2.10.2</version>
</dependency>
<dependency>
    <groupId>com.egzosn</groupId>
    <artifactId>pay-java-wx</artifactId>
    <version>2.10.2</version>
</dependency>

第三步 创建一个wx支付配置类WXConfig

package com.dyt.service.util;

import com.github.wxpay.sdk.WXPayConfig;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

public class WXConfigUtil implements WXPayConfig {
	private byte[] certData;
	public static final String APP_ID = "填写appid";
	public static final String KEY = "填写商户秘钥"; //在微信商户平台上设置API密钥
	public static final String MCH_ID = "填写商户id"; 

	@Override
	public String getAppID() {
		return APP_ID;
	}
	@Override
	public String getMchID() {
		return MCH_ID;
	}

	@Override
	public String getKey() {
		return KEY;
	}

	@Override
	public InputStream getCertStream() {
		ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
		return certBis;
	}

	@Override
	public int getHttpConnectTimeoutMs() {
		return 8000;
	}

	@Override
	public int getHttpReadTimeoutMs() {
		return 10000;
	}
}

第四步 serviceimpl实现层

package com.dyt.service.impl;

import com.dyt.dao.administrator1.OrderTableDao;
import com.dyt.dao.administrator1.PointsManageDao;
import com.dyt.pojo.entity.OrderTable;
import com.dyt.service.WxService;
import com.dyt.service.util.WXConfigUtil;
import com.dyt.util.StringUtil;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Service
@Component
@Transactional
public class WxServiceImpl implements WxService {
	
	@Autowired
	private OrderTableDao orderTableDao;

	//本地ip
	public static final String SPBILL_CREATE_IP = "服务器的IP地址";
	//异步回调地址
	 public static final String NOTIFY_URL = "回调接口链接";
	//支付方式
	 public static final String TRADE_TYPE_APP = "APP";
    @Override
    public String payBack(String resXml) {
        System.out.println("resXml******:"+resXml);
        WXConfigUtil config = null;
        try {
            config = new WXConfigUtil();
        } catch (Exception e) {
            e.printStackTrace();
        }
        WXPay wxpay = new WXPay(config);
        String xmlBack = "";
        Map<String, String> notifyMap = null;
        try {
            notifyMap = WXPayUtil.xmlToMap(resXml);         // 调用官方SDK转换成map类型数据
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//验证签名是否有效,有效则进一步处理
                String return_code = notifyMap.get("return_code");//状态
                System.out.println("return_code******"+return_code);
                String out_trade_no = notifyMap.get("out_trade_no");//商户订单号
                if (return_code.equals("SUCCESS")) {
                    if (out_trade_no != null) {
  // 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户的订单状态从退款改成支付成功
  // 注意特殊情况:微信服务端同样的通知可能会多次发送给商户系统,所以数据持久化之前需要检查是否已经处理过了,处理了直接返回成功标志
                    	OrderTable order = new OrderTable();
        				order.setOrderNum(out_trade_no);
        				OrderTable orderTable =orderTableDao.queryOrderTable(order);
        				if(!StringUtil.isNullOrEmpty(orderTable)) {
        					OrderTable orderTable1 = new OrderTable();
        					orderTable1.setId(orderTable.getId());
        					orderTable1.setIsPay(true);
        					orderTable1.setPayTime(new Date());
        					orderTable1.setPayWay("微信支付");
        					orderTableDao.update(orderTable1);

        				}
                        xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    } else {
                        //log.info("微信手机支付回调失败订单号:{}", out_trade_no);
                        xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                    }
                }
                return xmlBack;
            } else {
                // 签名错误,如果数据里没有sign字段,也认为是签名错误
                //失败的数据要不要存储?
                //log.error("手机支付回调通知签名错误");
                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                return xmlBack;
            }
        } catch (Exception e) {
            //log.error("手机支付回调通知失败", e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }

    @Override
    public Map doUnifiedOrder(OrderTable order)  {
        // 发起微信支付
        WXPay wxpay = null;
        Map<String, String> result = new HashMap<>();
        try{
            //处理订单金额
            OrderTable orderTable =orderTableDao.queryOrderTable(order);
            DecimalFormat df = new DecimalFormat();
            Double price = Double.valueOf(df.format(orderTable.getPrice()));
            int money = (int)(price * 100);
            WXConfigUtil config = new WXConfigUtil();
            wxpay = new WXPay(config);
            Map<String, String> data = new HashMap<String, String>();
            data.put("appid", config.getAppID());  //appid
            data.put("mch_id", config.getMchID());
            data.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串
            data.put("body", "大养之家会员充值");
            data.put("out_trade_no", orderTable.getOrderNum()); // 订单唯一编号, 不允许重复
            data.put("total_fee", String.valueOf(money)); // 订单金额, 单位分
            data.put("spbill_create_ip", SPBILL_CREATE_IP); // 下单ip
            data.put("notify_url", NOTIFY_URL); // 订单结果通知, 微信主动回调此接口
            data.put("trade_type", TRADE_TYPE_APP); // 固定填写
            String sign = WXPayUtil.generateSignature(data,config.getKey());
            data.put("sign", sign);
            Map<String, String> response = wxpay.unifiedOrder(data);
            String returnCode = response.get("return_code");
            System.out.println("returnCode:"+returnCode);
            if (!"SUCCESS".equals(returnCode)) {
                return null;
            }
            String resultCode = response.get("result_code");
            System.out.println("resultCode:"+resultCode);
            if (!"SUCCESS".equals(resultCode)) {
                return null;
            }
            String prepay_id = response.get("prepay_id");
            System.out.println("prepay_id:"+prepay_id);
            if (prepay_id == null) {
                return null;
            }
            //  前端调起微信支付必要参数
            String packages = "prepay_id=" + prepay_id;
            Map<String, String> wxPayMap = new HashMap<String, String>();
            wxPayMap.put("appid", config.getAppID());
            wxPayMap.put("timestamp", System.currentTimeMillis()/1000+"");
            wxPayMap.put("noncestr", WXPayUtil.generateNonceStr());
            wxPayMap.put("prepayid", prepay_id);
            wxPayMap.put("partnerid",config.getMchID());
            wxPayMap.put("package","Sign=WXPay");
            String packageSign  = WXPayUtil.generateSignature(wxPayMap, config.getKey());
            wxPayMap.put("sign", packageSign );
            result.putAll(wxPayMap);
            return result;
        }catch (Exception e){
        }
        return null;
    }
}

第五步 service层

public interface WxService {
	
	String payBack(String resXml);

    Map doUnifiedOrder(OrderTable order) throws Exception;
}

第六步 controller层

package com.dyt.controller;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.dyt.pojo.entity.OrderDetail;
import com.dyt.pojo.entity.OrderTable;
import com.dyt.pojo.entity.ProductOnShelf;
import com.dyt.service.OrderDetailService;
import com.dyt.service.OrderTableService;
import com.dyt.service.ProductOnShelfService;
import com.dyt.service.WxService;
import com.dyt.util.R;
import com.dyt.utils.WXConfigUtil;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

@Api(tags = "微信支付方式")
@Controller
@RequestMapping("orderwx")
public class OrderWxcontroller {
	private String str1 = "";
	@Reference
	private WxService wxService;
	@Reference
	private OrderDetailService orderDetailService;
	@Reference
	private OrderTableService orderTableService;
	@Reference
	private ProductOnShelfService productOnShelfService;
    
protected final static Logger logger = LoggerFactory.getLogger(OrderWxcontroller.class);

	@ApiOperation(value = "微信支付")
	@ApiResponses(value = { @ApiResponse(code = 200, message = "操作成功,返回列表,保存在data集合元素中"),
	@ApiResponse(code = 500, message = "内部错误,信息由msg字段返回") })
	@GetMapping (value ="Wxpay")
	@ResponseBody
	public R<Map> Wxpay(OrderTable order) {
		try {
			wxService.doUnifiedOrder(order);
			return R.ok(wxService.doUnifiedOrder(order));
		} catch (Exception e) {
			logger.error("微信支付接口失败 error : {}", e);
			e.printStackTrace();
			return R.error("微信支付数据失败----->" + e.getMessage());
		}

	}

	@ApiOperation(value = "微信回调")
	@ApiResponses(value = { @ApiResponse(code = 200, message = "操作成功,返回列表,保存在data集合元素中"),
	@ApiResponse(code = 500, message = "内部错误,信息由msg字段返回") })
	@PostMapping(value = "wxPayNotify")
	@ResponseBody
	public R<String> wxPayNotify(HttpServletRequest request) {
		String resXml = "";
		try {
			InputStream inputStream = request.getInputStream();
			// 将InputStream转换成xmlString
			BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
			StringBuilder sb = new StringBuilder();
			String line = null;
			try {
				while ((line = reader.readLine()) != null) {
					sb.append(line + "\n");
				}
			} catch (IOException e) {
				System.out.println(e.getMessage());
			} finally {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			resXml = sb.toString();
			String result = wxService.payBack(resXml);
			WXConfigUtil config = new WXConfigUtil();
			WXPay wxpay = new WXPay(config);
			Map<String, String> notifyMap = WXPayUtil.xmlToMap(resXml); 
            // 调用官方SDK转换成map类型数据
			if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                // 验证签名是否有效,有效则进一步处理
				String return_code = notifyMap.get("return_code");// 状态
				String out_trade_no = notifyMap.get("out_trade_no");// 商户订单号
				if (return_code.equals("SUCCESS")) {
					if (out_trade_no != null) {
						//业务处理
					}
				}
			}
			return R.ok(result);

		} catch (Exception e) {
			logger.error("微信回调接口失败 error : {}", e);
			e.printStackTrace();
			String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
					+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
			return R.error("微信回调数据失败----->" + e.getMessage());
		}
	}
}

第七步 android 对接

1.在build.gradle中引入

//微信支付
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'

2.创建WXPayEntryActivity

package com.example.dayangzhijia.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelpay.PayResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
    private IWXAPI api;

    public WXPayEntryActivity() {
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.api = WXAPIFactory.createWXAPI(this, "填写appid");
        this.api.handleIntent(this.getIntent(), this);
    }

    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        this.setIntent(intent);
        this.api.handleIntent(intent, this);
    }

    public void onReq(BaseReq req) {
    }

    public void onResp(BaseResp resp) {
        Toast.makeText(this,"errstr:"+resp.toString()+"  errcode:"+resp.errCode , Toast.LENGTH_SHORT).show();
        PayResp respP = (PayResp) resp;
        String payType = respP.extData;
        switch (payType) {
            case "OrderPay":        //订单支付的回调
                //Toast.makeText(this, "订单付款成功!", Toast.LENGTH_SHORT).show();
                if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
                    if (resp.errCode == 0) {
                        Toast.makeText(this, "订单付款成功!", Toast.LENGTH_SHORT).show();
                        finish();
                    } else if (resp.errCode == -2) {
                        Toast.makeText(this, "您已取消付款!", Toast.LENGTH_SHORT).show();
                        finish();
                    }else {
                        Toast.makeText(this, "参数错误", Toast.LENGTH_SHORT).show();
                        finish();
                    }
                } else{
                    finish();
                }
                break;
        }
    }
}

3. 业务调用

以下为主要代码,具体看自己业务。

@SuppressLint("WrongConstant")
private void wxPay() {
    OkHttpUtils.get().url(AppNetConfig.Wxpay)
        .addParams("orderNum", OrderNum)
        .build().execute(new StringCallback() {
        @Override
        public void onError(Call call, Exception e, int i) {
            Toast.makeText(MakeMemberActivity.this, "请求失败...", 0).show();
        }
        @Override
        public void onResponse(String s, int i) {
            JSONObject jsonObject = JSON.parseObject(s);
            WxPayBean wxPayBean = JSON.parseObject(s, new TypeReference<WxPayBean>() {
            });
            Toast.makeText(MakeMemberActivity.this, "获取订单中...", 0).show();
            // 通过WXAPIFactory工厂,获取IWXAPI的实例 
      api = WXAPIFactory.createWXAPI(MakeMemberActivity.this, "填写appid");
      api.registerApp("填写appid"); //特别重要一定要填写
            Toast.makeText(MakeMemberActivity.this, "返回" + s, 0).show();
            Log.d("PAY_GET", "返回" + s);
            try {
                if (wxPayBean.getData() != null) {
                    PayReq req = new PayReq();
                    req.appId = wxPayBean.getData().getAppid();
                    req.partnerId = wxPayBean.getData().getPartnerid();
                    req.prepayId = wxPayBean.getData().getPrepayid();
                    req.packageValue = wxPayBean.getData().getPackageX();
                    req.nonceStr = wxPayBean.getData().getNoncestr();
                    req.timeStamp = wxPayBean.getData().getTimestamp();
                    req.sign = wxPayBean.getData().getSign();
                    req.extData = "RechargePay";
                    Toast.makeText(MakeMemberActivity.this, "正常调起支付", Toast.LENGTH_SHORT).show();
                    api.sendReq(req); //调起微信
                } else {
                    Log.d("PAY_GET", "返回错误" + jsonObject.getString("retmsg"));
                    Toast.makeText(MakeMemberActivity.this, "返回错误" + jsonObject.getString("retmsg"), Toast.LENGTH_SHORT).show();
                }
            } catch (Exception var8) {
                Log.e("PAY_GET", "异常:" + var8.getMessage());
                Toast.makeText(MakeMemberActivity.this, "异常:" + var8.getMessage(), 0).show();
            }
        }
    });
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值