feta: paypal 支付渠道
This commit is contained in:
parent
2508a262ba
commit
66f42e85e2
|
|
@ -718,6 +718,8 @@ INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_LITE', '微信小程序')
|
||||||
INSERT INTO t_pay_way (way_code, way_name) VALUES ('YSF_BAR', '云闪付条码');
|
INSERT INTO t_pay_way (way_code, way_name) VALUES ('YSF_BAR', '云闪付条码');
|
||||||
INSERT INTO t_pay_way (way_code, way_name) VALUES ('YSF_JSAPI', '云闪付jsapi');
|
INSERT INTO t_pay_way (way_code, way_name) VALUES ('YSF_JSAPI', '云闪付jsapi');
|
||||||
|
|
||||||
|
INSERT INTO t_pay_way (way_code, way_name) VALUES ('PP_PC', 'Paypal PC 支付');
|
||||||
|
|
||||||
-- 初始化支付接口定义
|
-- 初始化支付接口定义
|
||||||
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
|
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
|
||||||
VALUES ('alipay', '支付宝官方', 1, 1, 2,
|
VALUES ('alipay', '支付宝官方', 1, 1, 2,
|
||||||
|
|
@ -742,3 +744,11 @@ VALUES ('ysfpay', '云闪付官方', 0, 1, 1,
|
||||||
NULL,
|
NULL,
|
||||||
'[{"wayCode": "YSF_BAR"}, {"wayCode": "ALI_JSAPI"}, {"wayCode": "WX_JSAPI"}, {"wayCode": "ALI_BAR"}, {"wayCode": "WX_BAR"}]',
|
'[{"wayCode": "YSF_BAR"}, {"wayCode": "ALI_JSAPI"}, {"wayCode": "WX_JSAPI"}, {"wayCode": "ALI_BAR"}, {"wayCode": "WX_BAR"}]',
|
||||||
'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/ysfpay.png', 'red', 1, '云闪付官方通道');
|
'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/ysfpay.png', 'red', 1, '云闪付官方通道');
|
||||||
|
|
||||||
|
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
|
||||||
|
VALUES ('pppay', 'Paypal 支付', 1, 0, 1,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
'[{"name":"sandbox","desc":"环境配置","type":"radio","verify":"required","values":"1,0","titles":"沙箱环境, 生产环境"},{"name":"clientId","desc":"Client ID","type":"text","verify":"required"},{"name":"secret","desc":"Secret","type":"text","verify":"required"},{"name":"refundWebhook","desc":"退款 Webhook id","type":"text","verify":"required"},{"name":"notifyWebhook","desc":"通知 Webhook id","type":"text","verify":"required"}]',
|
||||||
|
'[{"wayCode": "PP_PC"}]',
|
||||||
|
'https://payment-public.oss-cn-shenzhen.aliyuncs.com/ifBG/0b6c2cc3-d31b-4f5c-b076-f13c74d80b85.png', '#005ea6', 1, 'Paypal官方通道');
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,7 @@ public class CS {
|
||||||
String WXPAY = "wxpay"; // 微信官方支付
|
String WXPAY = "wxpay"; // 微信官方支付
|
||||||
String YSFPAY = "ysfpay"; // 云闪付开放平台
|
String YSFPAY = "ysfpay"; // 云闪付开放平台
|
||||||
String XXPAY = "xxpay"; // 小新支付
|
String XXPAY = "xxpay"; // 小新支付
|
||||||
|
String PPPAY = "pppay"; // Paypal 支付
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -169,6 +170,8 @@ public class CS {
|
||||||
String WX_BAR = "WX_BAR"; //微信条码支付
|
String WX_BAR = "WX_BAR"; //微信条码支付
|
||||||
String WX_H5 = "WX_H5"; //微信H5支付
|
String WX_H5 = "WX_H5"; //微信H5支付
|
||||||
String WX_NATIVE = "WX_NATIVE"; //微信扫码支付
|
String WX_NATIVE = "WX_NATIVE"; //微信扫码支付
|
||||||
|
|
||||||
|
String PP_PC = "PP_PC"; // Paypal 支付
|
||||||
}
|
}
|
||||||
|
|
||||||
//支付数据包 类型
|
//支付数据包 类型
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package com.jeequan.jeepay.core.model.params;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.jeequan.jeepay.core.constants.CS;
|
import com.jeequan.jeepay.core.constants.CS;
|
||||||
import com.jeequan.jeepay.core.model.params.alipay.AlipayNormalMchParams;
|
import com.jeequan.jeepay.core.model.params.alipay.AlipayNormalMchParams;
|
||||||
|
import com.jeequan.jeepay.core.model.params.pppay.PpPayNormalMchParams;
|
||||||
import com.jeequan.jeepay.core.model.params.wxpay.WxpayNormalMchParams;
|
import com.jeequan.jeepay.core.model.params.wxpay.WxpayNormalMchParams;
|
||||||
import com.jeequan.jeepay.core.model.params.xxpay.XxpayNormalMchParams;
|
import com.jeequan.jeepay.core.model.params.xxpay.XxpayNormalMchParams;
|
||||||
|
|
||||||
|
|
@ -38,6 +39,8 @@ public abstract class NormalMchParams {
|
||||||
return JSONObject.parseObject(paramsStr, AlipayNormalMchParams.class);
|
return JSONObject.parseObject(paramsStr, AlipayNormalMchParams.class);
|
||||||
}else if(CS.IF_CODE.XXPAY.equals(ifCode)){
|
}else if(CS.IF_CODE.XXPAY.equals(ifCode)){
|
||||||
return JSONObject.parseObject(paramsStr, XxpayNormalMchParams.class);
|
return JSONObject.parseObject(paramsStr, XxpayNormalMchParams.class);
|
||||||
|
}else if (CS.IF_CODE.PPPAY.equals(ifCode)){
|
||||||
|
return JSONObject.parseObject(paramsStr, PpPayNormalMchParams.class);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.jeequan.jeepay.core.model.params.pppay;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.jeequan.jeepay.core.model.params.NormalMchParams;
|
||||||
|
import com.jeequan.jeepay.core.utils.StringKit;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.core.model.params.pppay
|
||||||
|
* @create 2021/11/15 18:10
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PpPayNormalMchParams extends NormalMchParams {
|
||||||
|
/**
|
||||||
|
* 是否沙箱环境
|
||||||
|
*/
|
||||||
|
private Byte sandbox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clientId
|
||||||
|
* 客户端 ID
|
||||||
|
*/
|
||||||
|
private String clientId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* secret
|
||||||
|
* 密钥
|
||||||
|
*/
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付 Webhook 通知 ID
|
||||||
|
*/
|
||||||
|
private String notifyWebhook;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款 Webhook 通知 ID
|
||||||
|
*/
|
||||||
|
private String refundWebhook;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String deSenData() {
|
||||||
|
PpPayNormalMchParams mchParams = this;
|
||||||
|
if (StringUtils.isNotBlank(this.secret)) {
|
||||||
|
mchParams.setSecret(StringKit.str2Star(this.secret, 6, 6, 6));
|
||||||
|
}
|
||||||
|
return ((JSONObject) JSON.toJSON(mchParams)).toJSONString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -105,6 +105,13 @@
|
||||||
<artifactId>alipay-sdk-java</artifactId>
|
<artifactId>alipay-sdk-java</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- paypal 支付 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.paypal.sdk</groupId>
|
||||||
|
<artifactId>checkout-sdk</artifactId>
|
||||||
|
<version>1.0.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,4 +58,8 @@ public abstract class AbstractPaymentService implements IPaymentService{
|
||||||
return sysConfigService.getDBApplicationConfig().getPaySiteUrl() + "/api/pay/return/" + getIfCode();
|
return sysConfigService.getDBApplicationConfig().getPaySiteUrl() + "/api/pay/return/" + getIfCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getReturnUrl(String payOrderId){
|
||||||
|
return sysConfigService.getDBApplicationConfig().getPaySiteUrl() + "/api/pay/return/" + getIfCode() + "/" + payOrderId;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
package com.jeequan.jeepay.pay.channel.pppay;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.jeequan.jeepay.core.constants.CS;
|
||||||
|
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||||
|
import com.jeequan.jeepay.core.exception.ResponseException;
|
||||||
|
import com.jeequan.jeepay.pay.channel.AbstractChannelNoticeService;
|
||||||
|
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.channel.pppay
|
||||||
|
* @create 2021/11/15 20:58
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class PppayChannelNoticeService extends AbstractChannelNoticeService {
|
||||||
|
@Override
|
||||||
|
public String getIfCode() {
|
||||||
|
return CS.IF_CODE.PPPAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MutablePair<String, Object> parseParams(HttpServletRequest request, String urlOrderId, NoticeTypeEnum noticeTypeEnum) {
|
||||||
|
if (noticeTypeEnum == NoticeTypeEnum.DO_NOTIFY) {
|
||||||
|
JSONObject params = JSONUtil.parseObj(getReqParamJSON().toJSONString());
|
||||||
|
String orderId = params.getByPath("resource.purchase_units[0].invoice_id", String.class);
|
||||||
|
return MutablePair.of(orderId, params);
|
||||||
|
} else {
|
||||||
|
if (urlOrderId == null || urlOrderId.isEmpty()) {
|
||||||
|
throw ResponseException.buildText("ERROR");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
JSONObject params = JSONUtil.parseObj(getReqParamJSON().toString());
|
||||||
|
return MutablePair.of(urlOrderId, params);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("error", e);
|
||||||
|
throw ResponseException.buildText("ERROR");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelRetMsg doNotice(HttpServletRequest request, Object params, PayOrder payOrder, MchAppConfigContext mchAppConfigContext, NoticeTypeEnum noticeTypeEnum) {
|
||||||
|
try {
|
||||||
|
if (noticeTypeEnum == NoticeTypeEnum.DO_RETURN) {
|
||||||
|
return doReturn(request, params, payOrder, mchAppConfigContext);
|
||||||
|
}
|
||||||
|
return doNotify(request, params, payOrder, mchAppConfigContext);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("error", e);
|
||||||
|
throw ResponseException.buildText("ERROR");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelRetMsg doReturn(HttpServletRequest request, Object params, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws IOException {
|
||||||
|
JSONObject object = (JSONObject) params;
|
||||||
|
String ppOrderId = object.getStr("token");
|
||||||
|
return mchAppConfigContext.getPaypalWrapper().processOrder(ppOrderId, payOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelRetMsg doNotify(HttpServletRequest request, Object params, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws IOException {
|
||||||
|
JSONObject object = (JSONObject) params;
|
||||||
|
String ppOrderId = object.getByPath("resource.id", String.class);
|
||||||
|
return mchAppConfigContext.getPaypalWrapper().processOrder(ppOrderId, payOrder, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.jeequan.jeepay.pay.channel.pppay;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.jeequan.jeepay.core.constants.CS;
|
||||||
|
import com.jeequan.jeepay.core.entity.RefundOrder;
|
||||||
|
import com.jeequan.jeepay.core.exception.ResponseException;
|
||||||
|
import com.jeequan.jeepay.pay.channel.AbstractChannelRefundNoticeService;
|
||||||
|
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
|
||||||
|
import com.jeequan.jeepay.pay.model.PaypalWrapper;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||||
|
import com.paypal.core.PayPalHttpClient;
|
||||||
|
import com.paypal.http.HttpResponse;
|
||||||
|
import com.paypal.http.serializer.Json;
|
||||||
|
import com.paypal.payments.Refund;
|
||||||
|
import com.paypal.payments.RefundsGetRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.channel.pppay
|
||||||
|
* @create 2021/11/16 20:39
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class PppayChannelRefundNoticeService extends AbstractChannelRefundNoticeService {
|
||||||
|
@Override
|
||||||
|
public String getIfCode() {
|
||||||
|
return CS.IF_CODE.PPPAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MutablePair<String, Object> parseParams(HttpServletRequest request, String urlOrderId, NoticeTypeEnum noticeTypeEnum) {
|
||||||
|
JSONObject params = JSONUtil.parseObj(getReqParamJSON().toJSONString());
|
||||||
|
String orderId = params.getByPath("resource.invoice_id", String.class);
|
||||||
|
return MutablePair.of(orderId, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelRetMsg doNotice(HttpServletRequest request, Object params, RefundOrder refundOrder, MchAppConfigContext mchAppConfigContext, NoticeTypeEnum noticeTypeEnum) {
|
||||||
|
try {
|
||||||
|
JSONObject object = (JSONObject) params;
|
||||||
|
String orderId = object.getByPath("resource.id", String.class);
|
||||||
|
|
||||||
|
PaypalWrapper wrapper = mchAppConfigContext.getPaypalWrapper();
|
||||||
|
PayPalHttpClient client = wrapper.getClient();
|
||||||
|
|
||||||
|
RefundsGetRequest refundRequest = new RefundsGetRequest(orderId);
|
||||||
|
HttpResponse<Refund> response = client.execute(refundRequest);
|
||||||
|
|
||||||
|
ChannelRetMsg channelRetMsg = ChannelRetMsg.waiting();
|
||||||
|
channelRetMsg.setResponseEntity(wrapper.textResp("ERROR"));
|
||||||
|
|
||||||
|
if (response.statusCode() == 200) {
|
||||||
|
String responseJson = new Json().serialize(response.result());
|
||||||
|
channelRetMsg = wrapper.dispatchCode(response.result().status(), channelRetMsg);
|
||||||
|
channelRetMsg.setChannelAttach(responseJson);
|
||||||
|
channelRetMsg.setChannelOrderId(response.result().id());
|
||||||
|
channelRetMsg.setResponseEntity(wrapper.textResp("SUCCESS"));
|
||||||
|
} else {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
|
||||||
|
channelRetMsg.setChannelErrCode("201");
|
||||||
|
channelRetMsg.setChannelErrMsg("异步退款失败,Paypal 响应非 200");
|
||||||
|
}
|
||||||
|
|
||||||
|
return channelRetMsg;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("error", e);
|
||||||
|
throw ResponseException.buildText("ERROR");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.jeequan.jeepay.pay.channel.pppay;
|
||||||
|
|
||||||
|
import com.jeequan.jeepay.core.constants.CS;
|
||||||
|
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||||
|
import com.jeequan.jeepay.pay.channel.IPayOrderQueryService;
|
||||||
|
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.channel.pppay
|
||||||
|
* @create 2021/11/15 21:02
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PppayPayOrderQueryService implements IPayOrderQueryService {
|
||||||
|
@Override
|
||||||
|
public String getIfCode() {
|
||||||
|
return CS.IF_CODE.PPPAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelRetMsg query(PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
|
||||||
|
return mchAppConfigContext.getPaypalWrapper().processOrder(null, payOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.jeequan.jeepay.pay.channel.pppay;
|
||||||
|
|
||||||
|
import com.jeequan.jeepay.core.constants.CS;
|
||||||
|
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||||
|
import com.jeequan.jeepay.pay.channel.AbstractPaymentService;
|
||||||
|
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.AbstractRS;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ;
|
||||||
|
import com.jeequan.jeepay.pay.util.PaywayUtil;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.channel.pppay
|
||||||
|
* @create 2021/11/15 18:17
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PppayPaymentService extends AbstractPaymentService {
|
||||||
|
@Override
|
||||||
|
public String getIfCode() {
|
||||||
|
return CS.IF_CODE.PPPAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupport(String wayCode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String preCheck(UnifiedOrderRQ bizRQ, PayOrder payOrder) {
|
||||||
|
return PaywayUtil.getRealPaywayService(this, payOrder.getWayCode()).preCheck(bizRQ, payOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractRS pay(UnifiedOrderRQ bizRQ, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
|
||||||
|
return PaywayUtil.getRealPaywayService(this, payOrder.getWayCode()).pay(bizRQ, payOrder, mchAppConfigContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
package com.jeequan.jeepay.pay.channel.pppay;
|
||||||
|
|
||||||
|
import com.jeequan.jeepay.core.constants.CS;
|
||||||
|
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||||
|
import com.jeequan.jeepay.core.entity.RefundOrder;
|
||||||
|
import com.jeequan.jeepay.pay.channel.AbstractRefundService;
|
||||||
|
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
|
||||||
|
import com.jeequan.jeepay.pay.model.PaypalWrapper;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.refund.RefundOrderRQ;
|
||||||
|
import com.paypal.core.PayPalHttpClient;
|
||||||
|
import com.paypal.http.HttpResponse;
|
||||||
|
import com.paypal.http.serializer.Json;
|
||||||
|
import com.paypal.payments.*;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.channel.pppay
|
||||||
|
* @create 2021/11/16 20:20
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PppayRefundService extends AbstractRefundService {
|
||||||
|
@Override
|
||||||
|
public String getIfCode() {
|
||||||
|
return CS.IF_CODE.PPPAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String preCheck(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelRetMsg refund(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
|
||||||
|
if (payOrder.getChannelOrderNo() == null) {
|
||||||
|
return ChannelRetMsg.confirmFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
PaypalWrapper paypalWrapper = mchAppConfigContext.getPaypalWrapper();
|
||||||
|
|
||||||
|
String ppOrderId = paypalWrapper.processOrder(payOrder.getChannelOrderNo()).get(0);
|
||||||
|
String ppCatptId = paypalWrapper.processOrder(payOrder.getChannelOrderNo()).get(1);
|
||||||
|
|
||||||
|
if (ppOrderId == null || ppCatptId == null) {
|
||||||
|
return ChannelRetMsg.confirmFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
PayPalHttpClient client = paypalWrapper.getClient();
|
||||||
|
|
||||||
|
long amount = (bizRQ.getRefundAmount() / 100);
|
||||||
|
String amountStr = Long.toString(amount, 10);
|
||||||
|
String currency = bizRQ.getCurrency().toUpperCase();
|
||||||
|
|
||||||
|
RefundRequest refundRequest = new RefundRequest();
|
||||||
|
Money money = new Money();
|
||||||
|
money.currencyCode(currency);
|
||||||
|
money.value(amountStr);
|
||||||
|
|
||||||
|
refundRequest.invoiceId(refundOrder.getRefundOrderId());
|
||||||
|
refundRequest.amount(money);
|
||||||
|
refundRequest.noteToPayer(bizRQ.getRefundReason());
|
||||||
|
|
||||||
|
CapturesRefundRequest request = new CapturesRefundRequest(ppCatptId);
|
||||||
|
request.prefer("return=representation");
|
||||||
|
request.requestBody(refundRequest);
|
||||||
|
HttpResponse<Refund> response = client.execute(request);
|
||||||
|
|
||||||
|
ChannelRetMsg channelRetMsg = ChannelRetMsg.waiting();
|
||||||
|
channelRetMsg.setResponseEntity(paypalWrapper.textResp("ERROR"));
|
||||||
|
|
||||||
|
if (response.statusCode() == 201) {
|
||||||
|
String responseJson = new Json().serialize(response.result());
|
||||||
|
channelRetMsg = paypalWrapper.dispatchCode(response.result().status(), channelRetMsg);
|
||||||
|
channelRetMsg.setChannelAttach(responseJson);
|
||||||
|
channelRetMsg.setChannelOrderId(response.result().id());
|
||||||
|
channelRetMsg.setResponseEntity(paypalWrapper.textResp("SUCCESS"));
|
||||||
|
} else {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
|
||||||
|
channelRetMsg.setChannelErrCode("201");
|
||||||
|
channelRetMsg.setChannelErrMsg("请求退款失败,Paypal 响应非 201");
|
||||||
|
}
|
||||||
|
|
||||||
|
return channelRetMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelRetMsg query(RefundOrder refundOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
|
||||||
|
if (refundOrder.getChannelOrderNo() == null) {
|
||||||
|
return ChannelRetMsg.confirmFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
PaypalWrapper wrapper = mchAppConfigContext.getPaypalWrapper();
|
||||||
|
PayPalHttpClient client = wrapper.getClient();
|
||||||
|
|
||||||
|
RefundsGetRequest refundRequest = new RefundsGetRequest(refundOrder.getPayOrderId());
|
||||||
|
HttpResponse<Refund> response = client.execute(refundRequest);
|
||||||
|
|
||||||
|
ChannelRetMsg channelRetMsg = ChannelRetMsg.waiting();
|
||||||
|
channelRetMsg.setResponseEntity(wrapper.textResp("ERROR"));
|
||||||
|
|
||||||
|
if (response.statusCode() == 201) {
|
||||||
|
String responseJson = new Json().serialize(response.result());
|
||||||
|
channelRetMsg = wrapper.dispatchCode(response.result().status(), channelRetMsg);
|
||||||
|
channelRetMsg.setChannelAttach(responseJson);
|
||||||
|
channelRetMsg.setChannelOrderId(response.result().id());
|
||||||
|
channelRetMsg.setResponseEntity(wrapper.textResp("SUCCESS"));
|
||||||
|
} else {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
|
||||||
|
channelRetMsg.setChannelErrCode("201");
|
||||||
|
channelRetMsg.setChannelErrMsg("请求退款详情失败,Paypal 响应非 200");
|
||||||
|
}
|
||||||
|
|
||||||
|
return channelRetMsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
package com.jeequan.jeepay.pay.channel.pppay.payway;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||||
|
import com.jeequan.jeepay.core.exception.BizException;
|
||||||
|
import com.jeequan.jeepay.pay.channel.pppay.PppayPaymentService;
|
||||||
|
import com.jeequan.jeepay.pay.model.MchAppConfigContext;
|
||||||
|
import com.jeequan.jeepay.pay.model.PaypalWrapper;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.AbstractRS;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.payorder.payway.PPPcOrderRQ;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.payorder.payway.PPPcOrderRS;
|
||||||
|
import com.paypal.http.HttpResponse;
|
||||||
|
import com.paypal.http.serializer.Json;
|
||||||
|
import com.paypal.orders.*;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.channel.pppay.payway
|
||||||
|
* @create 2021/11/15 18:59
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service("pppayPaymentByPPPCService")
|
||||||
|
public class PpPc extends PppayPaymentService {
|
||||||
|
@Override
|
||||||
|
public String preCheck(UnifiedOrderRQ bizRQ, PayOrder payOrder) {
|
||||||
|
PPPcOrderRQ rq = (PPPcOrderRQ) bizRQ;
|
||||||
|
if (StringUtils.isEmpty(rq.getCancelUrl())) {
|
||||||
|
throw new BizException("用户取消支付回调[cancelUrl]不可为空");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
|
||||||
|
PPPcOrderRQ bizRQ = (PPPcOrderRQ) rq;
|
||||||
|
|
||||||
|
OrderRequest orderRequest = new OrderRequest();
|
||||||
|
|
||||||
|
ApplicationContext applicationContext = new ApplicationContext()
|
||||||
|
.brandName(mchAppConfigContext.getMchApp().getAppName())
|
||||||
|
.landingPage("NO_PREFERENCE")
|
||||||
|
.cancelUrl(bizRQ.getCancelUrl())
|
||||||
|
.returnUrl(getReturnUrl(payOrder.getPayOrderId()))
|
||||||
|
.userAction("PAY_NOW")
|
||||||
|
.shippingPreference("NO_SHIPPING");
|
||||||
|
|
||||||
|
orderRequest.applicationContext(applicationContext);
|
||||||
|
orderRequest.checkoutPaymentIntent("CAPTURE");
|
||||||
|
|
||||||
|
List<PurchaseUnitRequest> purchaseUnitRequests = new ArrayList<>();
|
||||||
|
|
||||||
|
long amount = (payOrder.getAmount() / 100);
|
||||||
|
String amountStr = Long.toString(amount, 10);
|
||||||
|
String currency = payOrder.getCurrency().toUpperCase();
|
||||||
|
|
||||||
|
PurchaseUnitRequest purchaseUnitRequest = new PurchaseUnitRequest()
|
||||||
|
.customId(payOrder.getPayOrderId())
|
||||||
|
.invoiceId(payOrder.getPayOrderId())
|
||||||
|
.amountWithBreakdown(new AmountWithBreakdown()
|
||||||
|
.currencyCode(currency)
|
||||||
|
.value(amountStr)
|
||||||
|
.amountBreakdown(
|
||||||
|
new AmountBreakdown().itemTotal(new Money().currencyCode(currency).value(amountStr))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.items(new ArrayList<Item>() {
|
||||||
|
{
|
||||||
|
add(
|
||||||
|
new Item()
|
||||||
|
.name(payOrder.getSubject())
|
||||||
|
.description(payOrder.getBody())
|
||||||
|
.sku(payOrder.getPayOrderId())
|
||||||
|
.unitAmount(new Money().currencyCode(currency).value(amountStr))
|
||||||
|
.quantity("1")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
purchaseUnitRequests.add(purchaseUnitRequest);
|
||||||
|
orderRequest.purchaseUnits(purchaseUnitRequests);
|
||||||
|
|
||||||
|
PaypalWrapper palApiConfig = mchAppConfigContext.getPaypalWrapper();
|
||||||
|
|
||||||
|
OrdersCreateRequest request = new OrdersCreateRequest();
|
||||||
|
request.header("prefer", "return=representation");
|
||||||
|
request.requestBody(orderRequest);
|
||||||
|
HttpResponse<Order> response = palApiConfig.getClient().execute(request);
|
||||||
|
|
||||||
|
PPPcOrderRS res = new PPPcOrderRS();
|
||||||
|
ChannelRetMsg channelRetMsg = new ChannelRetMsg();
|
||||||
|
|
||||||
|
if (response.statusCode() == 201) {
|
||||||
|
Order order = response.result();
|
||||||
|
String status = response.result().status();
|
||||||
|
String tradeNo = response.result().id();
|
||||||
|
|
||||||
|
LinkDescription paypalLink = order.links().stream().reduce(null, (result, curr) -> {
|
||||||
|
if (curr.rel().equalsIgnoreCase("approve") && curr.method().equalsIgnoreCase("get")) {
|
||||||
|
result = curr;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
channelRetMsg.setChannelAttach(JSONUtil.toJsonStr(new Json().serialize(order)));
|
||||||
|
channelRetMsg.setChannelOrderId(tradeNo + "," + "null");
|
||||||
|
|
||||||
|
if (status.equalsIgnoreCase("SAVED")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
|
||||||
|
} else if (status.equalsIgnoreCase("APPROVED")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
|
||||||
|
} else if (status.equalsIgnoreCase("VOIDED")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
|
||||||
|
} else if (status.equalsIgnoreCase("COMPLETED")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
|
||||||
|
} else if (status.equalsIgnoreCase("PAYER_ACTION_REQUIRED")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
|
||||||
|
} else if (status.equalsIgnoreCase("CREATED")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setPayUrl(paypalLink.href());
|
||||||
|
} else {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
|
||||||
|
channelRetMsg.setChannelErrCode("201");
|
||||||
|
channelRetMsg.setChannelErrMsg("请求失败,Paypal 响应非 201");
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setChannelRetMsg(channelRetMsg);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -50,6 +50,8 @@ public class MchAppConfigContext {
|
||||||
/** 放置所属服务商的信息 **/
|
/** 放置所属服务商的信息 **/
|
||||||
private IsvConfigContext isvConfigContext;
|
private IsvConfigContext isvConfigContext;
|
||||||
|
|
||||||
|
/** 缓存 Paypal 对象 **/
|
||||||
|
private PaypalWrapper paypalWrapper;
|
||||||
|
|
||||||
/** 缓存支付宝client 对象 **/
|
/** 缓存支付宝client 对象 **/
|
||||||
private AlipayClientWrapper alipayClientWrapper;
|
private AlipayClientWrapper alipayClientWrapper;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
package com.jeequan.jeepay.pay.model;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.jeequan.jeepay.core.entity.PayOrder;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
|
||||||
|
import com.paypal.core.PayPalEnvironment;
|
||||||
|
import com.paypal.core.PayPalHttpClient;
|
||||||
|
import com.paypal.http.HttpResponse;
|
||||||
|
import com.paypal.http.serializer.Json;
|
||||||
|
import com.paypal.orders.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.model
|
||||||
|
* @create 2021/11/15 19:10
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PaypalWrapper {
|
||||||
|
private PayPalEnvironment environment;
|
||||||
|
private PayPalHttpClient client;
|
||||||
|
|
||||||
|
private String notifyWebhook;
|
||||||
|
private String refundWebhook;
|
||||||
|
|
||||||
|
|
||||||
|
public ChannelRetMsg processOrder(String token, PayOrder payOrder) throws IOException {
|
||||||
|
return processOrder(token, payOrder, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<String> processOrder(String order) {
|
||||||
|
return processOrder(order, "null");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> processOrder(String order, String afterOrderId) {
|
||||||
|
String ppOrderId = "null";
|
||||||
|
String ppCatptId = "null";
|
||||||
|
if (order != null) {
|
||||||
|
if (order.contains(",")) {
|
||||||
|
String[] split = order.split(",");
|
||||||
|
if (split.length == 2) {
|
||||||
|
ppCatptId = split[1];
|
||||||
|
ppOrderId = split[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (afterOrderId != null && !afterOrderId.equalsIgnoreCase("null")) {
|
||||||
|
ppOrderId = afterOrderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ppCatptId.equalsIgnoreCase("null")) {
|
||||||
|
ppCatptId = null;
|
||||||
|
}
|
||||||
|
if (ppOrderId.equalsIgnoreCase("null")) {
|
||||||
|
ppOrderId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Arrays.asList(ppOrderId, ppCatptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelRetMsg processOrder(String token, PayOrder payOrder, boolean isCapture) throws IOException {
|
||||||
|
String ppOrderId = this.processOrder(payOrder.getChannelOrderNo(), token).get(0);
|
||||||
|
String ppCatptId = this.processOrder(payOrder.getChannelOrderNo()).get(1);
|
||||||
|
|
||||||
|
ChannelRetMsg channelRetMsg = ChannelRetMsg.waiting();
|
||||||
|
channelRetMsg.setResponseEntity(textResp("ERROR"));
|
||||||
|
|
||||||
|
// 如果订单 ID 还不存在,等待
|
||||||
|
if (ppOrderId == null) {
|
||||||
|
channelRetMsg.setChannelErrCode("201");
|
||||||
|
channelRetMsg.setChannelErrMsg("捕获订单请求失败");
|
||||||
|
return channelRetMsg;
|
||||||
|
} else {
|
||||||
|
Order order;
|
||||||
|
|
||||||
|
channelRetMsg.setChannelOrderId(ppOrderId + "," + "null");
|
||||||
|
|
||||||
|
// 如果 捕获 ID 不存在
|
||||||
|
if (ppCatptId == null && isCapture) {
|
||||||
|
OrderRequest orderRequest = new OrderRequest();
|
||||||
|
OrdersCaptureRequest ordersCaptureRequest = new OrdersCaptureRequest(ppOrderId);
|
||||||
|
ordersCaptureRequest.requestBody(orderRequest);
|
||||||
|
|
||||||
|
HttpResponse<Order> response = this.getClient().execute(ordersCaptureRequest);
|
||||||
|
|
||||||
|
if (response.statusCode() != 201) {
|
||||||
|
channelRetMsg.setChannelErrCode("201");
|
||||||
|
channelRetMsg.setChannelErrMsg("捕获订单请求失败");
|
||||||
|
return channelRetMsg;
|
||||||
|
}
|
||||||
|
order = response.result();
|
||||||
|
} else {
|
||||||
|
OrdersGetRequest request = new OrdersGetRequest(ppOrderId);
|
||||||
|
HttpResponse<Order> response = this.getClient().execute(request);
|
||||||
|
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
channelRetMsg.setChannelOrderId(ppOrderId);
|
||||||
|
channelRetMsg.setChannelErrCode("200");
|
||||||
|
channelRetMsg.setChannelErrMsg("请求订单详情失败");
|
||||||
|
return channelRetMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
order = response.result();
|
||||||
|
}
|
||||||
|
|
||||||
|
String status = order.status();
|
||||||
|
String orderJsonStr = new Json().serialize(order);
|
||||||
|
JSONObject orderJson = JSONUtil.parseObj(orderJsonStr);
|
||||||
|
|
||||||
|
for (PurchaseUnit purchaseUnit : order.purchaseUnits()) {
|
||||||
|
if (purchaseUnit.payments() != null) {
|
||||||
|
for (Capture capture : purchaseUnit.payments().captures()) {
|
||||||
|
ppCatptId = capture.id();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String orderUserId = orderJson.getByPath("payer.payer_id", String.class);
|
||||||
|
|
||||||
|
ChannelRetMsg result = new ChannelRetMsg();
|
||||||
|
result.setNeedQuery(true);
|
||||||
|
result.setChannelOrderId(ppOrderId + "," + ppCatptId); // 渠道订单号
|
||||||
|
result.setChannelUserId(orderUserId); // 支付用户ID
|
||||||
|
result.setChannelAttach(orderJsonStr); // Capture 响应数据
|
||||||
|
result.setResponseEntity(textResp("SUCCESS")); // 响应数据
|
||||||
|
result.setChannelState(ChannelRetMsg.ChannelState.WAITING); // 默认支付中
|
||||||
|
|
||||||
|
if (status.equalsIgnoreCase("COMPLETED")) {
|
||||||
|
result.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
|
||||||
|
} else if (status.equalsIgnoreCase("VOIDED")) {
|
||||||
|
result.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelRetMsg dispatchCode(String status, ChannelRetMsg channelRetMsg) {
|
||||||
|
if (status.equalsIgnoreCase("CANCELLED")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
|
||||||
|
} else if (status.equalsIgnoreCase("PENDING")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
|
||||||
|
} else if (status.equalsIgnoreCase("COMPLETED")) {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS);
|
||||||
|
} else {
|
||||||
|
channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.UNKNOWN);
|
||||||
|
}
|
||||||
|
return channelRetMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseEntity textResp(String text) {
|
||||||
|
HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
|
httpHeaders.setContentType(MediaType.TEXT_HTML);
|
||||||
|
return new ResponseEntity(text, httpHeaders, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -146,6 +146,10 @@ public class UnifiedOrderRQ extends AbstractMchAppRQ {
|
||||||
AliQrOrderRQ bizRQ = JSONObject.parseObject(StringUtils.defaultIfEmpty(this.channelExtra, "{}"), AliQrOrderRQ.class);
|
AliQrOrderRQ bizRQ = JSONObject.parseObject(StringUtils.defaultIfEmpty(this.channelExtra, "{}"), AliQrOrderRQ.class);
|
||||||
BeanUtils.copyProperties(this, bizRQ);
|
BeanUtils.copyProperties(this, bizRQ);
|
||||||
return bizRQ;
|
return bizRQ;
|
||||||
|
}else if (CS.PAY_WAY_CODE.PP_PC.equals(wayCode)){
|
||||||
|
PPPcOrderRQ bizRQ = JSONObject.parseObject(StringUtils.defaultIfEmpty(this.channelExtra, "{}"), PPPcOrderRQ.class);
|
||||||
|
BeanUtils.copyProperties(this, bizRQ);
|
||||||
|
return bizRQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.jeequan.jeepay.pay.rqrs.payorder.payway;
|
||||||
|
|
||||||
|
import com.jeequan.jeepay.core.constants.CS;
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.payorder.CommonPayDataRQ;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.rqrs.payorder.payway
|
||||||
|
* @create 2021/11/15 17:52
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PPPcOrderRQ extends CommonPayDataRQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品描述信息
|
||||||
|
**/
|
||||||
|
@NotBlank(message = "取消支付返回站点")
|
||||||
|
private String cancelUrl;
|
||||||
|
|
||||||
|
public PPPcOrderRQ() {
|
||||||
|
this.setWayCode(CS.PAY_WAY_CODE.PP_PC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.jeequan.jeepay.pay.rqrs.payorder.payway;
|
||||||
|
|
||||||
|
import com.jeequan.jeepay.pay.rqrs.payorder.CommonPayDataRS;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* @author 陈泉
|
||||||
|
* @package com.jeequan.jeepay.pay.rqrs.payorder.payway
|
||||||
|
* @create 2021/11/15 19:56
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PPPcOrderRS extends CommonPayDataRS {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -25,10 +25,13 @@ import com.jeequan.jeepay.core.model.params.IsvsubMchParams;
|
||||||
import com.jeequan.jeepay.core.model.params.NormalMchParams;
|
import com.jeequan.jeepay.core.model.params.NormalMchParams;
|
||||||
import com.jeequan.jeepay.core.model.params.alipay.AlipayIsvParams;
|
import com.jeequan.jeepay.core.model.params.alipay.AlipayIsvParams;
|
||||||
import com.jeequan.jeepay.core.model.params.alipay.AlipayNormalMchParams;
|
import com.jeequan.jeepay.core.model.params.alipay.AlipayNormalMchParams;
|
||||||
|
import com.jeequan.jeepay.core.model.params.pppay.PpPayNormalMchParams;
|
||||||
import com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvParams;
|
import com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvParams;
|
||||||
import com.jeequan.jeepay.core.model.params.wxpay.WxpayNormalMchParams;
|
import com.jeequan.jeepay.core.model.params.wxpay.WxpayNormalMchParams;
|
||||||
import com.jeequan.jeepay.pay.model.*;
|
import com.jeequan.jeepay.pay.model.*;
|
||||||
import com.jeequan.jeepay.service.impl.*;
|
import com.jeequan.jeepay.service.impl.*;
|
||||||
|
import com.paypal.core.PayPalEnvironment;
|
||||||
|
import com.paypal.core.PayPalHttpClient;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -223,6 +226,12 @@ public class ConfigContextService {
|
||||||
mchAppConfigContext.setWxServiceWrapper(WxServiceWrapper.buildWxServiceWrapper(wxpayParams));
|
mchAppConfigContext.setWxServiceWrapper(WxServiceWrapper.buildWxServiceWrapper(wxpayParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//放置 paypal client
|
||||||
|
PpPayNormalMchParams ppPayMchParams = mchAppConfigContext.getNormalMchParamsByIfCode(CS.IF_CODE.PPPAY, PpPayNormalMchParams.class);
|
||||||
|
if (ppPayMchParams != null) {
|
||||||
|
mchAppConfigContext.setPaypalWrapper(buildPaypalWrapper(ppPayMchParams.getSandbox(), ppPayMchParams.getSecret(), ppPayMchParams.getClientId(), ppPayMchParams.getNotifyWebhook(), ppPayMchParams.getRefundWebhook()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}else{ //服务商模式商户
|
}else{ //服务商模式商户
|
||||||
for (PayInterfaceConfig payInterfaceConfig : allConfigList) {
|
for (PayInterfaceConfig payInterfaceConfig : allConfigList) {
|
||||||
|
|
@ -317,6 +326,22 @@ public class ConfigContextService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PaypalWrapper buildPaypalWrapper(Byte sandbox, String secret, String clientID, String notifyHook, String refundHook) {
|
||||||
|
PaypalWrapper paypalWrapper = new PaypalWrapper();
|
||||||
|
|
||||||
|
PayPalEnvironment environment = new PayPalEnvironment.Live(clientID, secret);
|
||||||
|
|
||||||
|
if (sandbox == 1) {
|
||||||
|
environment = new PayPalEnvironment.Sandbox(clientID, secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
paypalWrapper.setEnvironment(environment);
|
||||||
|
paypalWrapper.setClient(new PayPalHttpClient(environment));
|
||||||
|
paypalWrapper.setNotifyWebhook(notifyHook);
|
||||||
|
paypalWrapper.setRefundWebhook(refundHook);
|
||||||
|
|
||||||
|
return paypalWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isCache(){
|
private boolean isCache(){
|
||||||
return SysConfigService.IS_USE_CACHE;
|
return SysConfigService.IS_USE_CACHE;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue