java支付宝提现功能,单笔转账到支付宝账户(公钥证书方式)

最近在开发商户分润系统(给商户分红),涉及到给商户账号提现功能,我们使用的是支付宝转账,通过公钥证书方式实现的。

 

在支付宝开放平台里找了好久的开发文档,但是介绍更多的是普通公钥的方式,这个方式比较简单,而且是支付宝比较推荐的方式,但是支付宝官方对公钥证书方式的介绍我个人觉得不是很全面,我这里就记录一下我的解决方案吧,如有不足还请谅解。

 

这里只介绍编码部分,至于支付宝端应用创建,密钥以及证书等下载在此忽略,请自行百度,证书以后是这个的

CSR文件夹下面是应用密钥,应用公钥

第一步:导包

        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.5.0.ALL</version>
        </dependency>
  • 当前仅Java版SDK(4.4.2.ALL及以上版本)支持证书签名方式,其他语言SDK还未支持。
  • Java版SDK 4.4.2.ALL中并没有对APP支付场景添加证书支持,若业务使用到该场景,请下载4.4.5.ALL及以上版本的SDK。(建议使用高版本的jar包)

 第二步:直接上代码



import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayFundTransOrderQueryRequest;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.response.AlipayFundTransOrderQueryResponse;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.bustil.profit.entity.Alipay;
import com.bustil.profit.inface.base.ResponseConstant;
import com.bustil.profit.util.base.ResponseDataVo;
import com.google.gson.Gson;
@Component
public class AliPay {
	
        //安全起见全部以配置文件方式
	@Value("${alipay-config.CHARSET}")
	private String CHARSET ;        
	@Value("${alipay-config.PAYEE_TYPE}")
	private String PAYEE_TYPE ;	
	@Value("${alipay-config.APP_ID}")
	private String APP_ID ;		
	@Value("${alipay-config.ALIPAY_URL}")
	private String ALIPAY_URL ;	
	@Value("${alipay-config.APP_PRIVATE_KEY}")
	private String APP_PRIVATE_KEY ;
	
	//支付宝公钥证书文件路径
	private static final String ALIPAY_CERT_PATH  =".\\conf\\alipayCert\\alipayCertPublicKey_RSA2.crt";
	//支付宝CA根证书文件路径
	private static final String ALIPAY_ROOT_CERT_PATH = ".\\conf\\alipayCert\\alipayRootCert.crt";
	//应用公钥证书路径
	private static final String APP_CERT_PAHT = ".\\conf\\alipayCert\\appCertPublicKey_2019080****89.crt";

//	public static void main(String[] args) {
//		System.out.println("-----------------------------开始转账-----------------------------");
//		try {
//			//alipayTransfer();
//			String tradingNo = "20190904****828275850";      //自己平台的唯一ID
//			String amount = "0.1";
//			String payeeAccount = "18*****3";    //这里填写收款人支付宝账号
//			String remark = "测试转账";
//			//alipayTransfer(tradingNo, amount, payeeAccount, remark);
//			alipayFundTransOrderQuery(tradingNo);
//		} catch (AlipayApiException e) {
//			e.printStackTrace();
//		}
//		System.out.println("-----------------------------转账结束-----------------------------");
//	}
//	
	
	/**
	 * 单笔转账到支付宝账号
	 * @author zhouhehe
	 * @param tradingNo		商户转账唯一订单号。发起转账来源方定义的转账单据ID,用于将转账回执通知给来源方。不同来源方给出的ID可以重复,同一个来源方必须保证其ID的唯一性。只支持半角英文、数字,及“-”、“_”。 
	 * @param amount		转账金额,单位:元。只支持2位小数,小数点前最大支持13位,金额必须大于等于0.1元。
	 * @param payeeAccount	收款方账户。与payee_type配合使用。付款方和收款方不能是同一个账户。 
	 * @param remark		转账备注(支持200个英文/100个汉字)。当付款方为企业账户,且转账金额达到(大于等于)50000元,remark不能为空。收款方可见,会展示在收款用户的收支详情中。
	 * @return
	 * @throws AlipayApiException
	 */
	public ResponseDataVo<Map<String, Object>> alipayTransfer(String tradingNo,String amount,String payeeAccount,String remark) throws AlipayApiException {
		//构造client
		CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
		certAlipayRequest.setServerUrl(ALIPAY_URL);
		certAlipayRequest.setAppId(APP_ID);
		certAlipayRequest.setPrivateKey(APP_PRIVATE_KEY);
		certAlipayRequest.setFormat("json");
		certAlipayRequest.setCharset(CHARSET);
		certAlipayRequest.setSignType("RSA2");
		//设置应用公钥证书路径
		certAlipayRequest.setCertPath(APP_CERT_PAHT);
		//设置支付宝公钥证书路径
		certAlipayRequest.setAlipayPublicCertPath(ALIPAY_CERT_PATH);
		//设置支付宝根证书路径
		certAlipayRequest.setRootCertPath(ALIPAY_ROOT_CERT_PATH);
		AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);

		
		AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
		Alipay alipay = new Alipay();
		alipay.setOut_biz_no(tradingNo);
		alipay.setPayee_type(PAYEE_TYPE);
		alipay.setAmount(amount);
		alipay.setPayer_show_name("******服务有限公司");
		alipay.setPayee_account(payeeAccount);
		//alipay.setPayee_real_name("哈哈哈哈");
		alipay.setRemark(remark);
		// 转成json格式放入
		String json = new Gson().toJson(alipay);
		request.setBizContent(json);
		AlipayFundTransToaccountTransferResponse response = null;
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			response = alipayClient.certificateExecute(request);
			if ("10000".equals(response.getCode())) {
				map.put("code", response.getCode());
				map.put("msg", response.getMsg());
				map.put("subCode", response.getSubCode());
				map.put("subMsg", response.getSubMsg());
				map.put("tradingNo", response.getOutBizNo());
				map.put("orderId", response.getOrderId());
				map.put("payDate", response.getPayDate());
				map.put("des", "转账成功");
				return ResponseDataVo.success(map);
			} else {
				map.put("code", response.getCode());
				map.put("msg", response.getMsg());
				map.put("subCode", response.getSubCode());
				map.put("subMsg", response.getSubMsg());
				map.put("tradingNo", response.getOutBizNo());
				map.put("orderId", response.getOrderId());
				map.put("payDate", response.getPayDate());
				map.put("des", "转账失败");
				return new ResponseDataVo<Map<String,Object>>(map, ResponseConstant.ERROR_CODE, "转账失败");
			}
		} catch (AlipayApiException e) {
			e.printStackTrace();
			map.put("success", "false");
			map.put("des", "转账失败!");
			return new ResponseDataVo<Map<String,Object>>(map, ResponseConstant.ERROR_CODE, "转账失败");
		}
	}
	
	/**
	 * 查询转账订单接口
	 * @author zhouhehe
	 * @param tradingNo	交易号	商户转账唯一订单号,分润系统唯一
	 * @return
	 * @throws AlipayApiException
	 */
	public ResponseDataVo<Map<String, Object>> alipayFundTransOrderQuery(String tradingNo) throws AlipayApiException {
		// 构造client
		CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
		certAlipayRequest.setServerUrl(ALIPAY_URL);
		certAlipayRequest.setAppId(APP_ID);
		certAlipayRequest.setPrivateKey(APP_PRIVATE_KEY);
		certAlipayRequest.setFormat("json");
		certAlipayRequest.setCharset(CHARSET);
		certAlipayRequest.setSignType("RSA2");
		// 设置应用公钥证书路径
		certAlipayRequest.setCertPath(APP_CERT_PAHT);
		// 设置支付宝公钥证书路径
		certAlipayRequest.setAlipayPublicCertPath(ALIPAY_CERT_PATH);
		// 设置支付宝根证书路径
		certAlipayRequest.setRootCertPath(ALIPAY_ROOT_CERT_PATH);
		AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);

		AlipayFundTransOrderQueryRequest request = new AlipayFundTransOrderQueryRequest();
		Alipay alipay = new Alipay();
		alipay.setOut_biz_no(tradingNo);
		// 转成json格式放入
		String json = new Gson().toJson(alipay);
		request.setBizContent(json);

		AlipayFundTransOrderQueryResponse response = null;

		Map<String, Object> map = new HashMap<String, Object>();
		try {
			response = alipayClient.certificateExecute(request);
			if ("10000".equals(response.getCode())) {
				map.put("code", response.getCode());
				map.put("msg", response.getMsg());
				map.put("orderId", response.getOrderId());
				map.put("payDate", response.getPayDate());
				map.put("status", response.getStatus());
				map.put("subCode", response.getSubCode());// 详情状态码
				map.put("des", "转账成功");
				return ResponseDataVo.success(map);
			} else {
				map.put("code", response.getCode());
				map.put("msg", response.getMsg());
				map.put("orderId", response.getOrderId());
				map.put("payDate", response.getPayDate());
				map.put("status", response.getStatus());
				map.put("subCode", response.getSubCode());// 详情状态码
				map.put("failReason", response.getFailReason());
				map.put("des", "转账失败");
				return new ResponseDataVo<Map<String,Object>>(map, ResponseConstant.ERROR_CODE, "转账失败");
			}
		} catch (AlipayApiException e) {
			e.printStackTrace();
			map.put("success", "false");
			map.put("des", "转账失败!");
			return new ResponseDataVo<Map<String,Object>>(map, ResponseConstant.ERROR_CODE, "转账失败");
		}
	}
}

这是一个测试demo,自测可用。

工具类添加一下:

package com.zhhtest.demozhh.inface;

public interface ResponseConstant {
	/**返回编码:成功**/
	Integer SUCCESS_CODE = 0;
	/**失败**/
	Integer ERROR_CODE = 1;
	int SESSION_DISABLED = 2;//登录超时
    int BUSINESS_ERROR = 3;//逻辑异常
    int SYSTEM_ERROR = 4;//系统错误
    int ACCESS_ERROR = 5;//无权限
    int CHECK_CODE_ERROR = 6;//验证码错误
    int TOKEN_NULL_ERROR = 7;//TOKEN为空
    int ACCOUNT_NOT_EXIST = 8;//用户名不存在
    int PASSWORD_ERROR = 9;//密码错误
    int PARAMETEN_MISS = 10;//没有传必要的参数
    int PARAMETEN_TYPE_ERROR = 11;//参数类型错误
	/**返回信息:成功**/
	String SUCCESS_MSG = "成功";
	String ERROR_MSG = "失败";
	String SESSION_DISABLED_MSG = "登录超时";
	String BUSINESS_ERROR_MSG = "逻辑异常";
	String SYSTEM_ERROR_MSG = "系统异常";
	String ACCESS_MSG = "无权限";
	String CHECK_CODE_ERROR_MSG = "验证码错误";
	String TOKEN_NULL_ERROR_MSG = "登录信息已过期";
	String ACCOUNT_NOT_EXIST_MSG = "用户不存在";
	String PASSWORD_ERROR_MSG = "密码错误";
	String PARAMETEN_MISS_MSG = "参数不完整";
	String PARAMETEN_TYPE_ERROR_MSG = "参数类型错误";//参数类型错误
}

工具类2:

package com.zhhtest.demozhh.utils;

import com.zhhtest.demozhh.inface.ResponseConstant;

import java.io.Serializable;

public class ResponseBaseVo implements Serializable {

    private static final long serialVersionUID = 4992866296675736795L;

    /**
     * 0 成功
     * 1 失败
     * 2 没有登录
     */
    protected Integer code;

    protected String message;

    public ResponseBaseVo() {
    }

    public ResponseBaseVo(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public static ResponseBaseVo success() {
        return new ResponseBaseVo(ResponseConstant.SUCCESS_CODE, ResponseConstant.SUCCESS_MSG);
    }

    public static ResponseBaseVo erro() {
        return erro(ResponseConstant.ERROR_MSG);
    }

    public static ResponseBaseVo erro(String message) {
        return new ResponseBaseVo(ResponseConstant.ERROR_CODE, message);
    }

    public static ResponseBaseVo loginTimeOut(){
        return new ResponseBaseVo(ResponseConstant.SESSION_DISABLED, ResponseConstant.BUSINESS_ERROR_MSG);
    }

    public static ResponseBaseVo logicalError(String msg){
        return new ResponseBaseVo(ResponseConstant.BUSINESS_ERROR, msg);
    }

    public static ResponseBaseVo logicalError(){
        return new ResponseBaseVo(ResponseConstant.BUSINESS_ERROR, ResponseConstant.BUSINESS_ERROR_MSG);
    }

    public static ResponseBaseVo systemError(String msg){
        return new ResponseBaseVo(ResponseConstant.SYSTEM_ERROR, ResponseConstant.SYSTEM_ERROR_MSG);
    }

    public static ResponseBaseVo accessError(String msg){
        return new ResponseBaseVo(ResponseConstant.ACCESS_ERROR, ResponseConstant.ACCESS_MSG);
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return JsonUtil.toJson(this);
    }

}

工具3:

package com.zhhtest.demozhh.utils;

import java.io.Serializable;

import com.zhhtest.demozhh.inface.ResponseConstant;

public class ResponseDataVo<T> extends ResponseBaseVo implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -8389534598865802502L;

	private T data;

	public ResponseDataVo() {

	}

	public ResponseDataVo(T data, Integer code, String message) {
		super(code, message);
		this.data = data;
	}
	
	public static <T> ResponseDataVo<T> success(T t) {
		return new ResponseDataVo<T>(t, ResponseConstant.SUCCESS_CODE, ResponseConstant.SUCCESS_MSG);
	}

	public static <T> ResponseDataVo<T> error() {
		return error(ResponseConstant.ERROR_MSG);
	}
	
	public static <T> ResponseDataVo<T> error(String message) {
		return new ResponseDataVo<T>(null, ResponseConstant.ERROR_CODE, message);
	}
	
	public static <T> ResponseDataVo<T> logicError(String message) {
		return new ResponseDataVo<T>(null, ResponseConstant.BUSINESS_ERROR, message);
	}

	public static <T> ResponseDataVo<T> sysError(String message) {
		return new ResponseDataVo<T>(null, ResponseConstant.SYSTEM_ERROR, message);
	}
	
	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}
}

平时不怎么写博客,如有不正确的地方还请指出

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值