支付宝app支付 java后台

相比较微信支付来说,个人感觉支付宝对开发者的友好度要好点,整理了一下之前项目中做的这个功能:

准备工作:

maven需要引入com.alipay.sdk:

<dependency>
	<groupId>com.alipay.sdk</groupId>
	<artifactId>alipay-sdk-java</artifactId>
    <version>3.0.0</version>
</dependency>

AlipayConfig:

public class AlipayConfig {
	 /** 支付宝支付业务:入参app_id */
    public static final String APPID = "此处为appid";

    /** 支付宝网关*/
    public static final String GATE = "https://openapi.alipay.com/gateway.do";

    /** (应用私钥)*/
    public static final String APP_PRIVATE_KEY = "此处填写应用密钥";

    /** (应用公钥)*/
    public static final String ALIPAY_PUBLIC_KEY = "此处填写应用公钥";

    /**  支付宝公钥 */
    public static final String PUBLIC_KEY = "此处为支付宝公钥";
    
    /** 合作伙伴ID(支付宝给定) */
    public static final String SELLERID = "此处为sellerid,支付宝针对每个apk都有特定的id";
    
    /** 商户账户 */
    public static final String SELLER = "此处为商户账号";
    
    /** 编码方式 */
    public static final String CHARSET = "utf-8";
    
	public AlipayConfig() {
	}
}

基础的参数配置如上,应该没有什么困难;

这里是实例化支付宝客户端时需要的参数, 可以参考支付宝开发文档:https://docs.open.alipay.com/204/105297/

AlipayUtil:

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;

public class AlipayUtil {
	private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(AlipayUtil.class);
	
	/**
	 * 创建商户订单  请求支付宝
	 * @param amount
	 * @param random
	 * @return
	 */
	public static String getsign(String amount,String random){
		//实例化客户端
		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.GATE, 
				AlipayConfig.APPID,
				AlipayConfig.APP_PRIVATE_KEY, 
				"json", AlipayConfig.CHARSET, 
				AlipayConfig.ALIPAY_PUBLIC_KEY, 
				"RSA2");
		 if (Double.valueOf(amount) <= 0){ // 一些必要的验证,防止抓包恶意修改支付金额
			 return null;
	     }
		 //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("我是测试数据");
        model.setSubject("祺科信息");
        model.setOutTradeNo(random);  //订单号
        model.setTimeoutExpress("30m");  // 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
        model.setTotalAmount(amount); // 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]这里调试每次支付1分钱,在项目上线前应将此处改为订单的总金额
        model.setProductCode("QUICK_MSECURITY_PAY");// 销售产品码,商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAY
        request.setBizModel(model);
        // 设置后台异步通知的地址,在手机端支付成功后支付宝会通知后台,手机端的真实支付结果依赖于此地址
        request.setNotifyUrl("http://catering.saimark.xusage.com/catering/a/RechargeUpdateFromAlipayNotify.xml");
        AlipayTradeAppPayResponse response = new AlipayTradeAppPayResponse();
        try {
            //这里和普通的接口调用不同,使用的是sdkExecute
            response = alipayClient.sdkExecute(request);
            System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response.getBody();
	}
	
	/**
	 * 支付宝支付成功后.异步请求该接口
	 * @param requestParams
	 * @return
	 */
	public static String aliPay_notify(Map requestParams){
        System.out.println("支付宝支付结果通知"+requestParams.toString());
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();

        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] + ",";
            }
          //乱码解决,这段代码在出现乱码时使用。
          //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
          params.put(name, valueStr);
         }
        //切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        try {
            boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
            if(flag){
                if("TRADE_SUCCESS".equals(params.get("trade_status"))){
                    //付款金额
                    String amount = params.get("buyer_pay_amount");
                    //商户订单号
                    String out_trade_no = params.get("out_trade_no");
                    //支付宝交易号
                    String trade_no = params.get("trade_no");
                    //附加数据
                    String passback_params = URLDecoder.decode(params.get("passback_params"));
                    LOGGER.debug("将要存入数据库的参数"+ amount+","+out_trade_no+","+trade_no+","+passback_params);
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
      return "success";
    }
	
	/** 
	  * 从request中获得参数Map,并返回可读的Map 
	  *  
	  * @param request 
	  * @return 
	  */  
	 @SuppressWarnings("unchecked")  
	 public static Map getParameterMap(HttpServletRequest request) {  
	     // 参数Map  
	     Map properties = request.getParameterMap();  
	     LOGGER.debug("包装参数:"+properties);
	     // 返回值Map  
	     Map<String, String> returnMap = new HashMap<String, String>();  
	     Iterator entries = properties.entrySet().iterator();  
	     Map.Entry entry;  
	     String name = "";  
	     String value = "";  
	     while (entries.hasNext()) {  
	         entry = (Map.Entry) entries.next();  
	         name = (String) entry.getKey();  
	         Object valueObj = entry.getValue();  
	         if(null == valueObj){  
	             value = "";  
	         }else if(valueObj instanceof String[]){  
	             String[] values = (String[])valueObj;  
	             for(int i=0;i<values.length;i++){  
	                 value = values[i] + ",";  
	             }  
	             value = value.substring(0, value.length()-1);  
	         }else{  
	             value = valueObj.toString();  
	         }  
	         returnMap.put(name, value);  
	     }  
	     return returnMap;  
	 }    
	
}

当app端传入参数请求java服务端时候,调用AlipayUtil.getsign(),获取sign值, getsign()传入的参数可以根据自己需求变化,做相应调整即可,一般来说app端只用后台返回给appid,private_key, orderInfo(即sign)三个参数即可;其他的事情交给Android端处理吧,

支付完成后,支付宝会根据事先定义好的url地址来请求我们服务端,来确认时候订单信息,我们从request中获取到请求的参数即可 request.getParameterMap(); 将map值传入AlipayUtil.aliPay_notify(map); 至此异步请求完成 ,可以再此方法里添加我们对数据库订单操作的逻辑。

根据需求决定是否添加单笔交易查询,来确认订单交易信息和状态,多重保障,如果感觉没有必要,接下来就不用再看啦;

单笔交易查询依旧挺方便:

 try {  
		    //实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型)  
		            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.GATE, AlipayConfig.APPID,   
		            AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET,   
		            AlipayConfig.PUBLIC_KEY,"RSA2");    //注意这里有个坑;  这里实例化客户端的时候用到的参数: AlipayConfig.PUBLIC_KEY; 创建订单时候的实例化客户端:AlipayConfig.ALIPAY_PUBLIC_KEY  两者不一样 注意区分
		    AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();  
		    alipayTradeQueryRequest.setBizContent("{" +  
		    "\"out_trade_no\":\""+parameter.getIndentId()+"\"" +  
		    "}");  
		    AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.execute(alipayTradeQueryRequest);    
		    if(alipayTradeQueryResponse.isSuccess()){  
		        //修改数据库支付宝订单表  
		    	//如果需要修改除了状态以外的参数;
		       /* alipaymentOrder.setTradeNo(alipayTradeQueryResponse.getTradeNo());  
		        alipaymentOrder.setBuyerLogonId(alipayTradeQueryResponse.getBuyerLogonId());  
		        alipaymentOrder.setTotalAmount(Double.parseDouble(alipayTradeQueryResponse.getTotalAmount()));  
		        alipaymentOrder.setReceiptAmount(Double.parseDouble(alipayTradeQueryResponse.getReceiptAmount()));  
		        alipaymentOrder.setInvoiceAmount(Double.parseDouble(alipayTradeQueryResponse.getInvoiceAmount()));  
		        alipaymentOrder.setBuyerPayAmount(Double.parseDouble(alipayTradeQueryResponse.getBuyerPayAmount()));  */
		        //更新表记录
		    } else {  
		    	LOGGER.info("==================调用支付宝查询接口失败!");  
		    }  
	    } catch (AlipayApiException e) {  
	        e.printStackTrace();  
	    }

通过alipayTradeQueryResponse.getTradeStatus()的值来判断订单交易状态;

有这几个情况:

      TRADE_FINISHED :交易结束并不可退款  

      TRADE_SUCCESS  :交易支付成功  

      TRADE_CLOSED  :未付款交易超时关闭或支付完成后全额退款  

      WAIT_BUYER_PAY  :交易创建并等待买家付款  

根据需要来做自己的逻辑处理即可;

因为时间比较久了,可能不是特别详细,不过应该没什么问题,欢迎各位大佬指导。

 

 

  • 1
    点赞
  • 5
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

阿门阿前那棵葡萄树

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值