ghy-all/ghy-payment/src/main/java/com/ghy/payment/service/AdapayService.java

537 lines
29 KiB
Java
Raw Normal View History

package com.ghy.payment.service;
import com.alibaba.fastjson.JSON;
2022-05-12 14:44:42 +08:00
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.AdapayConfig;
import com.ghy.common.adapay.AdapayProperties;
2022-05-12 14:44:42 +08:00
import com.ghy.common.adapay.model.*;
import com.ghy.common.enums.RefundType;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
2022-05-21 16:50:56 +08:00
import org.springframework.stereotype.Service;
2022-04-01 10:19:58 +08:00
import org.springframework.util.Assert;
2022-05-12 14:44:42 +08:00
import org.springframework.util.CollectionUtils;
import javax.validation.constraints.NotNull;
2022-05-12 14:44:42 +08:00
import java.util.Collection;
import java.util.List;
/**
* @author HH 2022/3/25
*/
@Slf4j
2022-05-21 16:50:56 +08:00
@Service
public class AdapayService {
private ThreadPoolTaskExecutor executor;
private AdapayProperties adapayProperties;
private CallBackService payCallbackService;
private CallBackService refundCallbackService;
private CallBackService drawCashCallbackService;
private CallBackService payReverseCallbackService;
@Autowired
public void setExecutor(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
this.executor = threadPoolTaskExecutor;
}
@Autowired
public void setAdapayProperties(AdapayProperties adapayProperties) {
log.info("Adapay load properties: {}", JSON.toJSONString(adapayProperties));
this.adapayProperties = adapayProperties;
}
@Autowired
public void setPayCallbackService(CallBackService payCallbackService) {
log.info("Adapay load callback: {}", payCallbackService.getClass().toString());
this.payCallbackService = payCallbackService;
}
@Autowired
public void setRefundCallbackService(CallBackService refundCallbackService) {
log.info("Adapay load callback: {}", refundCallbackService.getClass().toString());
this.refundCallbackService = refundCallbackService;
}
@Autowired
public void setDrawCashCallbackService(CallBackService drawCashCallbackService) {
log.info("Adapay load callback: {}", drawCashCallbackService.getClass().toString());
this.drawCashCallbackService = drawCashCallbackService;
}
@Autowired
public void setPayReverseCallbackService(CallBackService payReverseCallbackService) {
log.info("Adapay load callback: {}", payReverseCallbackService.getClass().toString());
this.payReverseCallbackService = payReverseCallbackService;
}
/**
2022-06-20 11:35:14 +08:00
* 查询支付对象
*
2022-06-20 11:35:14 +08:00
* @param deptId [必填]商户ID
* @param paymentId [必填] String(64) Adapay生成的支付对象id
* @return 支付对象
*/
2022-06-20 11:35:14 +08:00
public JSONObject getPayment(@NotNull Long deptId, @NotNull String paymentId) {
try {
return (JSONObject) Payment.query(paymentId, deptId.toString());
} catch (BaseAdaPayException e) {
e.printStackTrace();
}
return null;
}
/**
* 支付确认
* 适用于延时分账的场景只有已支付完成且延时分账的Payment对象才支持调用创建支付确认对象
* 支持一次全额或多次部分确认多次部分确认时当前确认金额 + 已确认金额 + 已撤销金额不能大于原支付金额
*
* @param deptId [必填]商户ID
* @param paymentId [必填] String(64) Adapay生成的支付对象id
* @param orderNo [必填] String(64) 请求订单号只能为英文数字或者下划线的一种或多种组合保证在app_id下唯一
* @param confirmAmt [必填] String(14) 确认金额必须大于0保留两位小数点如0.10100.05等必须小于等于原支付金额-已确认金额-已撤销金额
* @param divMembers 分账对象信息列表一次请求最多仅支持7个分账方json对象 形式详见 分账对象信息列表
2022-05-26 21:12:20 +08:00
* @param feeMode String(1) 手续费收取模式O-商户手续费账户扣取手续费I-交易金额中扣取手续费值为空时默认值为I若为O时分账对象列表中不支持传入手续费承担方
* @param description String(128) 附加说明
* @return 成功时同步返回一个包含 支付确认对象的JSON https://docs.adapay.tech/api/trade.html#id54
2022-12-13 23:51:14 +08:00
* 成功示例:{
* "order_no": "TEST18888888888_001",
* "created_time": "1670932918",
* "confirm_amt": "10.00",
* "confirmed_amt": "0.00",
* "reserved_amt": "0.00",
* "div_members": [{
* "member_id": "W7D888",
* "amount": "10.00",
* "fee_flag": "Y"
* }],
* "refunded_amt": "0.00",
* "prod_mode": "true",
* "id": "0021120221213200158990448709336858888888",
* "app_id": "app_01af32e7-6173-414f-88e5-79cae64d5e24",
* "fee_amt": "0.08",
* "object": "payment_confirm",
* "status": "succeeded"
* }
*/
public JSONObject paymentConfirm(@NotNull Long deptId, @NotNull String paymentId, @NotNull String orderNo,
@NotNull String confirmAmt, List<DivMember> divMembers,
String feeMode, String description) throws BaseAdaPayException {
JSONObject confirmParams = new JSONObject();
confirmParams.put("payment_id", paymentId);
confirmParams.put("order_no", orderNo);
confirmParams.put("confirm_amt", confirmAmt);
confirmParams.put("div_members", divMembers);
confirmParams.put("fee_mode", feeMode);
confirmParams.put("description", description);
log.info("发起支付确认 dept[{}] param:{}", deptId, confirmParams.toJSONString());
2023-01-30 20:41:50 +08:00
JSONObject response = (JSONObject) PaymentConfirm.create(confirmParams, deptId.toString());
log.info("支付确认结果 dept[{}] response:{}", deptId, response.toJSONString());
2023-01-30 20:41:50 +08:00
return response;
}
2022-05-12 14:44:42 +08:00
/**
* 创建余额支付请求
* 商户利用该接口进行余额支付支持同一商户下的商户-用户用户-商户用户-用户间的账户余额支付
*
2022-05-21 16:50:56 +08:00
* @param deptId [必填]商户ID
2022-05-12 14:44:42 +08:00
* @param orderNo [必填]请求订单号只能为英文数字或者下划线的一种或多种组合保证在app_id下唯一
* @param outMemberId [必填]出账用户的member_id 若为商户本身时请传入0
* @param inMemberId [必填]入账用户的member_id 若为商户本身时请传入0
* @param transAmt [必填]交易金额必须大于0人民币为元保留两位小数点"0.10""100.05"
* @param goodsTitle [必填]商品名称
* @param goodsDesc [必填]商品描述
* @param payMode 支付模式delay- 延时分账模式值为 delay div_members 字段必须为空
* 值为空时并且div_mermbers不为空时表示实时分账
* 值为空时并且div_mermbers也为空时表示不分账
* @param divMembers 分账对象信息列表最多仅支持7个分账方
* @return 成功时同步返回交易结果的 JSON
*/
public JSONObject balancePay(@NotNull Long deptId, @NotNull String orderNo, @NotNull String outMemberId,
@NotNull String inMemberId, @NotNull String transAmt, @NotNull String goodsTitle,
@NotNull String goodsDesc, String payMode, Collection<DivMember> divMembers) throws BaseAdaPayException {
2022-05-21 16:50:56 +08:00
// 获取商户的appId
String appId = AdapayConfig.getAppId(deptId);
JSONObject balanceParam = new JSONObject();
2022-05-21 16:50:56 +08:00
balanceParam.put("app_id", appId);
2022-05-12 14:44:42 +08:00
balanceParam.put("adapay_func_code", "settle_accounts.balancePay");
balanceParam.put("order_no", orderNo);
balanceParam.put("out_member_id", outMemberId);
balanceParam.put("in_member_id", inMemberId);
balanceParam.put("trans_amt", transAmt);
balanceParam.put("goods_title", goodsTitle);
balanceParam.put("goods_desc", goodsDesc);
balanceParam.put("pay_mode", payMode);
if (!CollectionUtils.isEmpty(divMembers)) {
balanceParam.put("div_members", divMembers);
}
return (JSONObject) AdapayCommon.requestAdapay(balanceParam, deptId.toString());
2022-05-12 14:44:42 +08:00
}
/**
* 创建结算账户对象 https://docs.adapay.tech/api/trade.html#settle-account-create
* 创建结算账户对象是为一个已创建用户对象创建结算账户用于对用户分账金额的结算目前仅支持绑定银行卡结算账户
* 用户创建对私结算账户时会对银行卡号银行卡开户姓名身份证号三要素认证若认证失败则创建结算账户失败
* 每个结算账户对象 Adapay 系统会生成一个唯一的 id可用于查询结算账户对象或者删除结算账户对象
*
2022-05-21 16:50:56 +08:00
* @param deptId [必填]商户ID
* @param memberId [必填]商户下的用户id只能为英文数字或者下划线的一种或多种组合保证在app_id下唯一
* @param cardId [必填]银行卡号
* @param cardName [必填]银行卡对应的户名
* @param telNo [必填]手机号
* @param bankAcctType [必填]银行账户类型1-对公2-对私
* @param certId 证件号银行账户类型为对私时必填
* @param bankCode 银行编码银行账户类型对公时必填详见附录 银行代码 https://docs.adapay.tech/api/appendix.html#id3
* @param provCode 银行账户开户银行所在省份编码 省市编码银行账户类型为对公时必填省市编码详见area.json
* @param areaCode 银行账户开户银行所在地区编码省市编码银行账户类型为对公时必填省市编码详见area.json
* @return 成功时同步返回一个包含 SettleAccount对象 JSON
*/
public JSONObject createSettleAccount(@NotNull Long deptId, @NotNull String memberId, @NotNull String cardId,
@NotNull String cardName, @NotNull String bankAcctType, String certId, String telNo,
String bankCode, String provCode, String areaCode) throws BaseAdaPayException {
2022-05-21 16:50:56 +08:00
// 获取商户的appId
String appId = AdapayConfig.getAppId(deptId);
// 结算账户信息 参见结算账户信息(AccountInfo)对象 https://docs.adapay.tech/api/appendix.html#accountinfo
JSONObject accountInfo = new JSONObject();
switch (bankAcctType) {
case "1":
Assert.isTrue(StringUtils.isNoneBlank(bankCode, provCode, areaCode),
"[bankCode, provCode, areaCode] cannot be empty !");
2022-05-12 14:44:42 +08:00
break;
case "2":
Assert.hasText(cardId, "cardId is blank !");
accountInfo.put("cert_type", "00");
accountInfo.put("cert_id", certId);
break;
default:
throw new BaseAdaPayException("Wrong bankAcctType !");
}
accountInfo.put("card_id", cardId);
accountInfo.put("card_name", cardName);
accountInfo.put("tel_no", telNo);
accountInfo.put("bank_code", bankCode);
accountInfo.put("bank_acct_type", bankAcctType);
accountInfo.put("prov_code", provCode);
accountInfo.put("area_code", areaCode);
JSONObject settleCountParams = new JSONObject();
settleCountParams.put("member_id", memberId);
2022-05-21 16:50:56 +08:00
settleCountParams.put("app_id", appId);
// 目前仅支持bank_account银行卡
settleCountParams.put("channel", "bank_account");
settleCountParams.put("account_info", accountInfo);
return (JSONObject) SettleAccount.create(settleCountParams, deptId.toString());
}
2023-03-21 12:46:38 +08:00
/**
* 查询商户或商户下某个用户结算账户的余额
*
* @param deptId [必填]商户ID
* @param memberId [必填]商户用户对象 id只能为英文数字或者下划线的一种或多种组合若查询商户本身时传入值0
* @param settleAccountId 由Adapay生成的结算账户对象id若查询商户本身时可为空而当查询商户下的用户时必填
* @param acctType 账户类型01或者为空是基本户02是手续费账户03是过渡户
* @return https://docs.adapay.tech/api/wallet.html#id13
* 成功示例: {"acct_balance": "0.00",
* "app_id": "app_XXXXXXXX",
* "avl_balance": "0.00",
* "frz_balance": "0.00",
* "last_avl_balance": "0.00",
* "object": "account_balance",
* "status": "succeeded",
* "prod_mode": "true"}
*/
public JSONObject queryAccountBalance(@NotNull Long deptId, @NotNull String memberId, String settleAccountId, String acctType) throws BaseAdaPayException {
// 获取商户的appId
String appId = AdapayConfig.getAppId(deptId);
JSONObject queryParams = new JSONObject(5);
queryParams.put("settle_account_id", settleAccountId);
queryParams.put("member_id", memberId);
queryParams.put("app_id", appId);
queryParams.put("acct_type", acctType);
return (JSONObject) SettleAccount.balance(queryParams, deptId.toString());
}
2023-03-12 18:00:23 +08:00
/**
* 删除结算账户对象 https://docs.adapay.tech/api/trade.html#id50
* 删除结算账户对象是对已创建完成的结算账户对象进行删除操作
* 删除结算账户成功后支付时不再支持分账功能您可再调用创建结算账户对象创建新的结算账户
* 删除结算账户对象需要 Adapay 系统生成的结算账户对象 id 进行删除
*
* @param deptId [必填]商户ID
* @param memberId [必填]商户下的用户id只能为英文数字或者下划线的一种或多种组合保证在app_id下唯一
* @param settleAccountId [必填]结算账户ID
* @return { "status": "succeeded", "id":"0006440476699456", "prod_mode": "true" }
*/
public JSONObject deleteSettleAccount(@NotNull Long deptId, @NotNull String memberId, @NotNull String settleAccountId) throws BaseAdaPayException {
String appId = AdapayConfig.getAppId(deptId);
JSONObject settleCountParams = new JSONObject();
settleCountParams.put("app_id", appId);
settleCountParams.put("settle_account_id", settleAccountId);
settleCountParams.put("member_id", memberId);
2023-03-12 22:59:11 +08:00
return (JSONObject) SettleAccount.delete(settleCountParams, deptId.toString());
2023-03-12 18:00:23 +08:00
}
/**
* 创建实名用户 https://docs.adapay.tech/api/trade.html#member-realname
*
2022-05-21 16:50:56 +08:00
* @param deptId [必填]商户ID
* @param memberId [必填]商户下的用户id只能为英文数字或者下划线的一种或多种组合保证在app_id下唯一
* @param telNo [必填]用户手机号
* @param username [必填]用户姓名
* @param certId [必填]证件号
* @return 成功时同步返回一个包含Member对象的JSON
*/
public JSONObject createMember(@NotNull Long deptId, @NotNull String memberId, @NotNull String telNo,
@NotNull String username, @NotNull String certId) throws BaseAdaPayException {
2022-05-21 16:50:56 +08:00
// 获取商户的appId
String appId = AdapayConfig.getAppId(deptId);
JSONObject memberParams = new JSONObject();
memberParams.put("member_id", memberId);
2022-05-21 16:50:56 +08:00
memberParams.put("app_id", appId);
memberParams.put("tel_no", telNo);
memberParams.put("user_name", username);
// 证件类型仅支持00-身份证
memberParams.put("cert_type", "00");
// 接口功能号
memberParams.put("adapay_func_code", "members.realname");
memberParams.put("cert_id", certId);
return (JSONObject) AdapayCommon.requestAdapay(memberParams, deptId.toString());
}
2022-04-01 10:19:58 +08:00
/**
* 对指定商户或者商户下用户的结算账户可用余额发起主动取现操作金额从账户中提到绑定的结算银行卡中
*
2022-05-21 16:50:56 +08:00
* @param deptId [必填]商户ID
2022-04-01 10:19:58 +08:00
* @param orderNo [必填项]请求订单号只能为英文数字或者下划线的一种或多种组合保证在app_id下唯一
* @param cashType [必填项]取现类型T1-T+1取现D1-D+1取现D0-即时取现
* @param cashAmt [必填项]取现金额必须大于0人民币为元保留两位小数点"0.10""100.05"
* @param memberId [必填项]用户对象的member_id若是商户本身取现时请传入0
* @param remark 备注
* @param feeMode 手续费收取模式O-商户手续费账户扣取手续费I-交易金额中扣取手续费值为空时默认值为I
* @return https://docs.adapay.tech/api/wallet.html#cash-response
*/
public JSONObject drawCash(@NotNull Long deptId, String orderNo, String cashType, String cashAmt,
String memberId, String remark, String feeMode) throws BaseAdaPayException {
2022-05-21 16:50:56 +08:00
// 获取商户的appId
String appId = AdapayConfig.getAppId(deptId);
2022-04-01 10:19:58 +08:00
Assert.hasText(orderNo, "orderNo is blank!");
Assert.hasText(cashType, "cashType is blank!");
Assert.hasText(cashAmt, "cashAmt is blank!");
Assert.hasText(memberId, "memberId is blank!");
JSONObject cashParam = new JSONObject();
2022-04-01 10:19:58 +08:00
cashParam.put("order_no", orderNo);
2022-05-21 16:50:56 +08:00
cashParam.put("app_id", appId);
2022-04-01 10:19:58 +08:00
cashParam.put("cash_type", cashType);
cashParam.put("cash_amt", cashAmt);
cashParam.put("member_id", memberId);
cashParam.put("notify_url", adapayProperties.getNotifyUrl());
cashParam.put("remark", remark);
cashParam.put("fee_mode", feeMode);
log.info("发起提现 dept[{}] param:{}", deptId, cashParam.toJSONString());
2022-05-31 20:55:09 +08:00
JSONObject response = (JSONObject) Drawcash.create(cashParam, deptId.toString());
log.info("提现结果 dept[{}] response:{}", deptId, response.toJSONString());
response.put("dept_id", deptId);
executor.execute(() -> drawCashCallbackService.onResponse(response));
2022-05-31 20:55:09 +08:00
return response;
2022-04-01 10:19:58 +08:00
}
/**
* 通过该功能可以查询已发起的取现交易状态
*
* @param deptId [必填]商户ID
* @param orderNo [必填项]请求订单号只能为英文数字或者下划线的一种或多种组合保证在app_id下唯一
* @return https://docs.adapay.tech/api/wallet.html#query-cash-response
* 失败示例: {"error_msg":"未查到相关取现信息","error_type":"invalid_request_error","prod_mode":"true","error_code":"cash_error","status":"failed"}
* 成功示例: {"cash_list":[{"cash_id":"0021110483925412449046528","trans_stat":"P","cash_amt":"19.87"}],"prod_mode":"true","status":"succeeded"}
*/
public JSONObject queryDrawCash(@NotNull Long deptId, @NotNull String orderNo) throws BaseAdaPayException {
Assert.hasText(orderNo, "orderNo is blank!");
JSONObject queryCashParam = new JSONObject();
queryCashParam.put("order_no", orderNo);
return (JSONObject) Drawcash.query(queryCashParam, deptId.toString());
}
/**
2022-03-31 10:38:34 +08:00
* 支付宝正扫支付
2022-03-29 20:17:36 +08:00
*/
public JSONObject alipayQrPay(@NotNull Long deptId, PayParam payParam,
AlipayExpend expend, DeviceInfo deviceInfo,
Collection<DivMember> divMembers) throws BaseAdaPayException {
return pay(deptId, "alipay_qr", payParam, expend, deviceInfo, divMembers);
2022-03-29 20:17:36 +08:00
}
/**
2022-05-11 20:10:00 +08:00
* 微信公众号支付
*/
public JSONObject wxPubPay(@NotNull Long deptId, PayParam payParam,
WxpayExpend expend, DeviceInfo deviceInfo,
Collection<DivMember> divMembers) throws BaseAdaPayException {
return pay(deptId, "wx_pub", payParam, expend, deviceInfo, divMembers);
}
2022-03-29 20:17:36 +08:00
/**
* 微信小程序支付
2022-03-31 10:38:34 +08:00
*/
public JSONObject wxLitePay(@NotNull Long deptId, PayParam payParam,
WxpayExpend expend, DeviceInfo deviceInfo,
Collection<DivMember> divMembers) throws BaseAdaPayException {
return pay(deptId, "wx_lite", payParam, expend, deviceInfo, divMembers);
2022-03-31 10:38:34 +08:00
}
/**
2022-05-21 16:50:56 +08:00
* 聚合支付
*
* @param deptId [必填]商户ID
2022-05-12 14:44:42 +08:00
* @param payChannel [必填项]支付渠道详见 https://docs.adapay.tech/api/appendix.html#id2
* @param payParam [必填项]支付参数
* @param expend 支付渠道额外参数 https://docs.adapay.tech/api/appendix.html#expend
* @param deviceInfo 前端设备信息 https://docs.adapay.tech/api/appendix.html#deviceinfo
* @param divMembers 分账对象信息列表 https://docs.adapay.tech/api/appendix.html#divmembers
2022-03-31 10:38:34 +08:00
* @return 同步返回一个 支付对象详见 https://docs.adapay.tech/api/trade.html#id2
2022-12-13 23:51:14 +08:00
* 成功示例: {
* "order_no": "TEST18888888888_001",
* "created_time": "1670932358",
* "party_order_id": "02212212137155817188888",
* "pay_amt": "10.00",
* "expend": {
* "qrcode_url": "https://qr.alipay.com/bax022139la4gqagxbti8888"
* },
* "prod_mode": "true",
* "pay_channel": "alipay_qr",
* "query_url": "https://api.adapay.tech/v1/expire/payments/1/cff1102a8a0d5d4be1d444acb7726fdd",
* "id": "002112022121319523810448706986096888888",
* "app_id": "app_01af32e7-6173-414f-88e5-79cae64d5e24",
* "object": "payment",
* "status": "succeeded"
* }
*/
public JSONObject pay(@NotNull Long deptId, @NotNull String payChannel, @NotNull PayParam payParam,
Expend expend, DeviceInfo deviceInfo,
Collection<DivMember> divMembers) throws BaseAdaPayException {
2022-05-21 16:50:56 +08:00
// 获取商户的appId
String appId = AdapayConfig.getAppId(deptId);
2022-05-12 14:44:42 +08:00
JSONObject paymentParams = payParam.toJSONObject();
2022-05-21 16:50:56 +08:00
paymentParams.put("app_id", appId);
paymentParams.put("notify_url", adapayProperties.getNotifyUrl());
2022-03-31 10:38:34 +08:00
paymentParams.put("pay_channel", payChannel);
2022-04-24 18:19:14 +08:00
paymentParams.put("div_members", divMembers);
2022-05-12 14:44:42 +08:00
paymentParams.put("device_info", deviceInfo);
2022-03-31 10:38:34 +08:00
paymentParams.put("expend", expend);
log.debug("paymentParams: {}", paymentParams.toJSONString());
JSONObject response = (JSONObject) Payment.create(paymentParams, deptId.toString());
executor.execute(() -> payCallbackService.onResponse(response));
return response;
}
2022-03-31 10:38:34 +08:00
/**
2022-06-20 11:35:14 +08:00
* 发起退款
2022-03-31 10:38:34 +08:00
* 当您的业务需要发起退款时可通过 Adapay 系统提供的创建 Refund对象 方法创建一个退款对象资金会原路退回用户的支付宝或微信中
* 支持一次全额或多次部分退款退款次数最多不超过10次多次部分退款时当前退款金额 + 已退款金额不能大于原支付金额
* 对于每次撤销交易Adapay 都会通过 异步消息通知 告知结果
* 退款对象同步返回成功表示Adapay受理成功退款结果以异步通知为准支持退款最长时间为178天
* 若返回码是order_id_not_exists 订单记录不存在既超过退款期限无法退款成功
*
* @param deptId [必填]商户ID
2022-03-31 10:38:34 +08:00
* @param paymentId [必填项]支付确认对象的id
* @param refundOrderNo [必填项]订单号
* @param refundAmt [必填项]退款金额若退款金额小于原交易金额则认为是部分退款必须大于0保留两位小数点如0.10100.05等
* @return 同步返回一个 退款对象 https://docs.adapay.tech/api/trade.html#create-refund-params
2022-03-31 10:38:34 +08:00
*/
public JSONObject refund(@NotNull Long deptId, @NotNull String paymentId,
@NotNull String refundOrderNo, @NotNull String refundAmt) throws BaseAdaPayException {
2022-04-01 10:19:58 +08:00
Assert.hasText(paymentId, "paymentId is blank!");
Assert.hasText(refundOrderNo, "refundOrderNo is blank!");
Assert.hasText(refundAmt, "refundAmt is blank!");
JSONObject refundParams = new JSONObject();
2022-03-31 10:38:34 +08:00
refundParams.put("refund_amt", refundAmt);
refundParams.put("refund_order_no", refundOrderNo);
2022-05-31 20:55:09 +08:00
JSONObject response = (JSONObject) Refund.create(paymentId, refundParams, deptId.toString());
executor.execute(() -> refundCallbackService.onResponse(response));
2022-05-31 20:55:09 +08:00
return response;
2022-03-31 10:38:34 +08:00
}
2022-03-29 20:17:36 +08:00
/**
* 支付关单
* 针对已经创建的 支付对象您可以调用关单接口进行交易的关闭调用此接口后该用户订单将不再能支付成功 对于关单功能的使用有如下规则
* 1.存在关单记录不能再次关单
* 2.交易时间 1分钟 内无法关单成功
* 3.正扫交易时间超过 2小时 无法关单成功
* 4.支付宝正扫接口如果用户没有扫码订单不能关闭成功二维码给用户展示如果用户没有用手机去扫码那这笔就不能关单 如果用户扫过了的话无需支付成功就可以关单了-微信正扫无此条限制
* 5.网银和快捷类交易都不支持关单操作
*
* @param deptId [必填]商户ID
2022-03-29 20:17:36 +08:00
* @param paymentId [必填项] Adapay 生成的支付对象 id
* @param reason 关单描述
* @param expend 扩展域
* @return 关单的结果将通过一个 JSON 同步返回 https://docs.adapay.tech/api/trade.html#close-payment-response
2022-03-29 20:17:36 +08:00
*/
public JSONObject close(@NotNull Long deptId, String paymentId, String reason, String expend) throws BaseAdaPayException {
2022-04-01 10:19:58 +08:00
Assert.hasText(paymentId, "paymentId is blank!");
JSONObject paymentParams = new JSONObject();
2022-03-29 20:17:36 +08:00
paymentParams.put("payment_id", paymentId);
paymentParams.put("reason", reason);
paymentParams.put("expend", expend);
return (JSONObject) Payment.close(paymentParams, deptId.toString());
2022-03-29 20:17:36 +08:00
}
/**
* 查询已创建的单个用户对象
* https://docs.adapay.tech/api/trade.html#id41
*
* @param deptId [必填]商户ID
* @param memberId [必填]商户下的用户id只能为英文数字或者下划线的一种或多种组合保证在app_id下唯一
* @return 成功时同步返回一个包含 Member对象的JSON
*/
public JSONObject queryMember(@NotNull Long deptId, @NotNull String memberId) throws BaseAdaPayException {
JSONObject memberParams = new JSONObject();
memberParams.put("member_id", memberId);
memberParams.put("app_id", AdapayConfig.getAppId(deptId));
return (JSONObject) Member.query(memberParams, deptId.toString());
}
2022-05-31 20:55:09 +08:00
/**
* 支付撤销
* 支付撤销对象适用于[延时分账]的场景只有已支付完成且为延时分账的Payment对象在没有创建支付确认对象成功之前可以调用创建支付撤销对象
* 用来撤销支付资金会原路退回用户的支付宝或微信中 支持一次全额或多次部分撤销撤销次数最多不超过10次
* 多次部分撤销时当前撤销金额 + 已撤销金额 + 已确认金额不能大于原支付金额
* 对于每次撤销交易Adapay 都会通过 异步消息通知 告知结果
* https://docs.adapay.tech/api/trade.html#payment-reverse-object
*
* @param deptId [必填]商户ID
* @param paymentId [必填]Adapay生成的支付对象id
* @param reverseAmt [必填]撤销金额必须大于0保留两位小数点如0.10100.05等
* 撤销金额必须小于等于支付金额 - 已确认金额 - 已撤销撤销成功+撤销中金额
* @param type 退款类型 回调时根据它找到对应的财务单
2022-05-31 20:55:09 +08:00
* @return 创建支付撤销对象同步返回成功表示 Adapay 受理成功撤销结果以异步通知为准
*/
public JSONObject payReverse(@NotNull Long deptId, @NotNull String paymentId, @NotNull String reverseAmt, @NotNull RefundType type) throws BaseAdaPayException {
2022-05-31 20:55:09 +08:00
JSONObject reverseParams = new JSONObject();
reverseParams.put("app_id", AdapayConfig.getAppId(deptId));
reverseParams.put("payment_id", paymentId);
reverseParams.put("reverse_amt", reverseAmt);
reverseParams.put("notify_url", adapayProperties.getNotifyUrl());
reverseParams.put("order_no", type.code + System.currentTimeMillis());
2022-06-01 16:29:52 +08:00
JSONObject response = (JSONObject) PaymentReverse.create(reverseParams, deptId.toString());
executor.execute(() -> payReverseCallbackService.onResponse(response));
2022-05-31 20:55:09 +08:00
return response;
}
/**
* 通过 Payment对象 id 查询一个已创建的 Payment对象
* 仅支持查询支付交易发起之后3天内的交易状态3天之后的交易状态请使用 对账单下载 对账或登陆 控制台 查询
*
* @param deptId [必填]商户ID
* @param paymentId [必填]Adapay生成的支付对象id
* @return https://docs.adapay.tech/api/trade.html#id17
*/
public JSONObject queryPayment(@NotNull Long deptId, @NotNull String paymentId) throws BaseAdaPayException {
return (JSONObject) Payment.query(paymentId, deptId.toString());
}
}