diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/PayPalV2PayController.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/PayPalV2PayController.java new file mode 100644 index 0000000..125c215 --- /dev/null +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/PayPalV2PayController.java @@ -0,0 +1,147 @@ +package com.egzosn.pay.demo.controller; + + +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; + +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.egzosn.pay.common.api.PayService; +import com.egzosn.pay.common.bean.DefaultCurType; +import com.egzosn.pay.common.bean.RefundOrder; +import com.egzosn.pay.common.bean.RefundResult; +import com.egzosn.pay.paypal.api.PayPalConfigStorage; +import com.egzosn.pay.paypal.v2.api.PayPalPayService; +import com.egzosn.pay.paypal.v2.bean.PayPalOrder; +import com.egzosn.pay.paypal.v2.bean.order.AddressPortable; +import com.egzosn.pay.paypal.v2.bean.order.Name; +import com.egzosn.pay.paypal.v2.bean.order.ShippingDetail; + +/** + * 发起支付入口 + * + * @author: egan + * email egzosn@gmail.com + * date 2018/05/06 10:30 + */ +@RestController +@RequestMapping("payPalV2") +public class PayPalV2PayController { + + + private PayService service = null; + + @PostConstruct + public void init() { + PayPalConfigStorage storage = new PayPalConfigStorage(); + storage.setClientID("AZDS0IhUZvJTO99unlvSDMfbZIP-p-UecYXZdJoweha9LFuqKXKcQIGZgfVaX6oGiAOJAUuJD7JwyTl1"); + storage.setClientSecret("EK2YaOrw3oLSDWIRzvb9BWGTjiPPhY1fFUu5ylhUsGYLc_h_dlpJ0hr_LDEkbO9MyKP2P83YcywbPaem"); + storage.setTest(true); + //发起付款后的页面转跳地址 + storage.setReturnUrl("http://www.egzosn.com/payPal/payBack.json"); + // 注意:这里不是异步回调的通知 IPN 地址设置的路径:https://developer.paypal.com/developer/ipnSimulator/ + //取消按钮转跳地址, + storage.setCancelUrl("http://www.egzosn.com/pay/cancel"); + service = new PayPalPayService(storage); + } + + + /** + * 跳到支付页面 + * 针对实时支付,即时付款 + * + * @param price 金额 + * @return 跳到支付页面 + */ + @RequestMapping(value = "toPay.html", produces = "text/html;charset=UTF-8") + public String toPay(BigDecimal price) { + //及时收款 + PayPalOrder order = new PayPalOrder(); + order.setBrandName("该标签将覆盖PayPal网站上PayPal帐户中的公司名称,非必填"); + order.setDescription("订单说明"); + order.setInvoiceId("非必填 API调用者为该订单提供的外部发票号码。出现在付款人的交易历史记录和付款人收到的电子邮件中。"); + order.setCustomId("非必填 api调用中没发现有任何用处 API调用者提供的外部ID。用于协调客户端交易与PayPal交易。出现在交易和结算报告中,但付款人不可见"); + order.setPrice(price); + order.setShippingDetail(new ShippingDetail() + .name(new Name().fullName("RATTA")) + .addressPortable(new AddressPortable() + .addressLine1("梅陇镇") + .addressLine2("集心路168号") + .adminArea2("闵行区") + .adminArea1("上海市") + .postalCode("20000") + .countryCode("CN"))); + String toPayHtml = service.toPay(order); + + //某些支付下单时无法设置单号,通过下单后返回对应单号,如 paypal,友店。 + String tradeNo = order.getTradeNo(); + System.out.println("支付订单号:" + tradeNo + " 这里可以进行回存"); + + return toPayHtml; + } + + /** + * 申请退款接口 + * + * @return 返回支付方申请退款后的结果 + */ + @RequestMapping("refund") + public RefundResult refund() { + // TODO 这里需要 refundAmount, curType, description, tradeNo + RefundOrder order = new RefundOrder(); + order.setCurType(DefaultCurType.USD); + order.setDescription(" description "); + order.setTradeNo("paypal 平台的单号, 支付下单返回的单号"); + order.setRefundAmount(BigDecimal.valueOf(0.01)); + return service.refund(order); + } + + + /** + * 注意:这里不是异步回调的通知 IPN 地址设置的路径:https://developer.paypal.com/developer/ipnSimulator/ + * PayPal确认付款调用的接口 + * 用户确认付款后,paypal调用的这个方法执行付款 + * + * @param request 请求 + * @return 付款成功信息 + * @throws IOException IOException + */ + @GetMapping(value = "payBackBefore.json") + public String payBackBefore(HttpServletRequest request) throws IOException { + try (InputStream is = request.getInputStream()) { + if (service.verify(service.getParameter2Map(request.getParameterMap(), is))) { + // TODO 这里进行成功后的订单业务处理 + // TODO 返回成功付款页面,这个到时候再做一个漂亮的页面显示,并使用前后端分离的模式 + return service.successPayOutMessage(null).toMessage(); + } + } + return "failure"; + } + + /* */ + + /** + * 支付回调地址 + * 注意:这里不是异步回调的通知 IPN 地址设置的路径:https://developer.paypal.com/developer/ipnSimulator/ + * + * @param request 请求 + * @return 结果 + * @throws IOException IOException + * 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)} + *
+ * 如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler} 那么会使用默认的 {@link com.egzosn.pay.common.api.DefaultPayMessageHandler} + */ + @RequestMapping(value = "payBack.json") + public String payBack(HttpServletRequest request) throws IOException { + //业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看com.egzosn.pay.common.api.PayService.setPayMessageHandler() + return service.payBack(request.getParameterMap(), request.getInputStream()).toMessage(); + } + + +} diff --git a/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/api/PayPalOutMessageBuilder.java b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/api/PayPalOutMessageBuilder.java new file mode 100644 index 0000000..71e19c4 --- /dev/null +++ b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/api/PayPalOutMessageBuilder.java @@ -0,0 +1,26 @@ +package com.egzosn.pay.paypal.v2.api; + +import java.util.Map; + +import com.egzosn.pay.common.bean.outbuilder.TextBuilder; + +/** + * @author Egan + *
+ * email egzosn@gmail.com + * date 2021/1/17 + *+ */ +public class PayPalOutMessageBuilder extends TextBuilder { + + + public PayPalOutMessageBuilder(Map
+ * email egzosn@gmail.com
+ * date 2021-1-16 22:15:09
+ */
+public class PayPalPayService extends BasePayService
+ * email egzosn@gmail.com
+ * date 2018/04/28 11:10
+ */
+public enum PayPalTransactionType implements TransactionType {
+ /**
+ * 获取token
+ */
+ AUTHORIZE("v1/oauth2/token"),
+ /**
+ * 付款 网页支付
+ */
+ CHECKOUT("v2/checkout/orders"),
+ /**
+ * 获取订单信息
+ */
+ ORDERS_GET("/v2/checkout/orders/{order_id}"),
+ /**
+ * 获取订单信息
+ */
+ ORDERS_CAPTURE("/v2/checkout/orders/{order_id}/capture"),
+ /**
+ * 获取订单信息
+ */
+ CAPTURE("/v2/payments/captures/{capture_id}"),
+ /**
+ * 退款
+ */
+ REFUND("/v2/payments/captures/{capture_id}/refund"),
+
+ /**
+ * 退款查询
+ */
+ REFUND_GET("/v2/payments/refunds/{refund_id}"),
+
+ ;
+
+
+ private String method;
+
+ private PayPalTransactionType(String method) {
+ this.method = method;
+ }
+
+ @Override
+ public String getType() {
+ return this.name();
+ }
+
+ /**
+ * 获取接口名称
+ *
+ * @return 接口名称
+ */
+ @Override
+ public String getMethod() {
+ return this.method;
+ }
+
+}
diff --git a/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/AddressPortable.java b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/AddressPortable.java
new file mode 100644
index 0000000..3abf421
--- /dev/null
+++ b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/AddressPortable.java
@@ -0,0 +1,220 @@
+package com.egzosn.pay.paypal.v2.bean.order;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * The portable international postal address. Maps to [AddressValidationMetadata](https://github.com/googlei18n/libaddressinput/wiki/AddressValidationMetadata) and HTML 5.1 [Autofilling form controls: the autocomplete attribute](https://www.w3.org/TR/html51/sec-forms.html#autofilling-form-controls-the-autocomplete-attribute).
+ */
+public class AddressPortable {
+
+ public AddressPortable() {
+ }
+
+ /**
+ * The first line of the address. For example, number or street. For example, `173 Drury Lane`. Required for data entry and compliance and risk checks. Must contain the full address.
+ */
+ @JSONField(name = "address_line_1")
+ private String addressLine1;
+
+ public String addressLine1() {
+ return addressLine1;
+ }
+
+ public AddressPortable addressLine1(String addressLine1) {
+ this.addressLine1 = addressLine1;
+ return this;
+ }
+
+ /**
+ * The second line of the address. For example, suite or apartment number.
+ */
+ @JSONField(name = "address_line_2")
+ private String addressLine2;
+
+ public String addressLine2() {
+ return addressLine2;
+ }
+
+ public AddressPortable addressLine2(String addressLine2) {
+ this.addressLine2 = addressLine2;
+ return this;
+ }
+
+ /**
+ * The third line of the address, if needed. For example, a street complement for Brazil, direction text, such as `next to Walmart`, or a landmark in an Indian address.
+ */
+ @JSONField(name = "address_line_3")
+ private String addressLine3;
+
+ public String addressLine3() {
+ return addressLine3;
+ }
+
+ public AddressPortable addressLine3(String addressLine3) {
+ this.addressLine3 = addressLine3;
+ return this;
+ }
+
+ /**
+ * The highest level sub-division in a country, which is usually a province, state, or ISO-3166-2 subdivision. Format for postal delivery. For example, `CA` and not `California`. Value, by country, is:
+ * email egzosn@gmail.com
+ * date 2021/1/12
+ *
+ */
+public class PayPalOrder extends PayOrder {
+
+ /**
+ * 该标签将覆盖PayPal网站上PayPal帐户中的公司名称
+ */
+ private String brandName;
+ /**
+ * 支付成功之后回调的页面
+ */
+ private String returnUrl;
+
+ /**
+ * 取消支付的页面
+ *
+ * 注意:这里不是异步回调的通知
+ * IPN 地址设置的路径:https://developer.paypal.com/developer/ipnSimulator/
+ *
+ */
+ private String cancelUrl;
+ /**
+ * LOGIN。当客户单击PayPal Checkout时,客户将被重定向到页面以登录PayPal并批准付款。
+ * BILLING。当客户单击PayPal Checkout时,客户将被重定向到一个页面,以输入信用卡或借记卡以及完成购买所需的其他相关账单信息
+ * NO_PREFERENCE。当客户单击“ PayPal Checkout”时,将根据其先前的交互方式将其重定向到页面以登录PayPal并批准付款,或重定向至页面以输入信用卡或借记卡以及完成购买所需的其他相关账单信息使用PayPal。
+ * 默认值:NO_PREFERENCE
+ */
+ private String landingPage = "NO_PREFERENCE";
+
+ /**
+ * GET_FROM_FILE。使用贝宝网站上客户提供的送货地址。
+ * NO_SHIPPING。从PayPal网站编辑送货地址。推荐用于数字商品
+ * SET_PROVIDED_ADDRESS。使用商家提供的地址。客户无法在PayPal网站上更改此地址
+ */
+ private String shippingPreference = "NO_SHIPPING";
+ /**
+ * CONTINUE。将客户重定向到PayPal付款页面后,将出现“ 继续”按钮。当结帐流程启动时最终金额未知时,请使用此选项,并且您想将客户重定向到商家页面而不处理付款。
+ * PAY_NOW。将客户重定向到PayPal付款页面后,出现“ 立即付款”按钮。当启动结帐时知道最终金额并且您要在客户单击“ 立即付款”时立即处理付款时,请使用此选项。
+ */
+ private String userAction = "CONTINUE";
+
+ private ShippingDetail shippingDetail;
+ /**
+ * API调用者为购买单元提供的外部ID。当您必须通过“补丁”更新订单时,需要多个购买单位。如果忽略该值,且订单只包含一个购买单元,PayPal将该值设置为' default '。
+ */
+ private String referenceId;
+ /**
+ * API调用者为该订单提供的外部发票号码。出现在付款人的交易历史记录和付款人收到的电子邮件中
+ */
+ private String invoiceId;
+
+
+ /**
+ * API调用者提供的外部ID。用于协调客户端交易与PayPal交易。出现在交易和结算报告中,但付款人不可见。
+ *
+ * @return 外部ID
+ */
+ public String getCustomId() {
+ return super.getOutTradeNo();
+ }
+
+ /**
+ * /**
+ * API调用者提供的外部ID。用于协调客户端交易与PayPal交易。出现在交易和结算报告中,但付款人不可见。
+ *
+ * @param customId 外部ID
+ */
+ public void setCustomId(String customId) {
+ super.setOutTradeNo(customId);
+ }
+
+
+ public String getDescription() {
+ return super.getSubject();
+ }
+
+ public void setDescription(String description) {
+ super.setSubject(description);
+ }
+
+
+ public String getCurrencyCode() {
+ CurType curType = super.getCurType();
+ if (null == curType) {
+ curType = DefaultCurType.USD;
+ }
+ return curType.getType();
+ }
+
+ public void setCurrencyCode(CurType currencyCode) {
+ super.setCurType(currencyCode);
+ }
+
+ public String getBrandName() {
+ return brandName;
+ }
+
+ public void setBrandName(String brandName) {
+ super.addAttr("brandName", brandName);
+ this.brandName = brandName;
+ }
+
+ public String getReturnUrl() {
+ return returnUrl;
+ }
+
+ public void setReturnUrl(String returnUrl) {
+ super.addAttr("returnUrl", returnUrl);
+ this.returnUrl = returnUrl;
+ }
+
+ public String getCancelUrl() {
+ return cancelUrl;
+ }
+
+ public void setCancelUrl(String cancelUrl) {
+ super.addAttr("cancelUrl", cancelUrl);
+ this.cancelUrl = cancelUrl;
+ }
+
+ public String getLandingPage() {
+ return landingPage;
+ }
+
+ public void setLandingPage(String landingPage) {
+ super.addAttr("landingPage", landingPage);
+ this.landingPage = landingPage;
+ }
+
+ public String getShippingPreference() {
+ return shippingPreference;
+ }
+
+ public void setShippingPreference(String shippingPreference) {
+ super.addAttr("shippingPreference", shippingPreference);
+ this.shippingPreference = shippingPreference;
+ }
+
+ public String getUserAction() {
+
+ return userAction;
+ }
+
+ public void setUserAction(String userAction) {
+ super.addAttr("userAction", userAction);
+ this.userAction = userAction;
+ }
+
+ public ShippingDetail getShippingDetail() {
+ return shippingDetail;
+ }
+
+ public void setShippingDetail(ShippingDetail shippingDetail) {
+ super.addAttr("shippingDetail", shippingDetail);
+ this.shippingDetail = shippingDetail;
+ }
+
+ public String getReferenceId() {
+ return referenceId;
+ }
+
+ public void setReferenceId(String referenceId) {
+ super.addAttr("referenceId", referenceId);
+ this.referenceId = referenceId;
+ }
+
+ public String getInvoiceId() {
+ return invoiceId;
+ }
+
+ public void setInvoiceId(String invoiceId) {
+ super.addAttr("invoiceId", referenceId);
+ this.invoiceId = invoiceId;
+ }
+}
diff --git a/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/PayPalRefundResult.java b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/PayPalRefundResult.java
new file mode 100644
index 0000000..551b8ca
--- /dev/null
+++ b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/PayPalRefundResult.java
@@ -0,0 +1,119 @@
+package com.egzosn.pay.paypal.v2.bean;
+
+import java.math.BigDecimal;
+import java.util.Map;
+
+import com.egzosn.pay.common.bean.BaseRefundResult;
+import com.egzosn.pay.common.bean.CurType;
+
+/**
+ * @author Egan
+ *
+ * email egzosn@gmail.com
+ * date 2021/1/16
+ *
+ */
+public class PayPalRefundResult extends BaseRefundResult {
+
+ /**
+ * 支付平台订单号,交易号
+ */
+ private String tradeNo;
+
+ public PayPalRefundResult(Map
+ * 说明交易类型主要用于支付接口调用参数所需
+ *
+ *
+ *
+ *
+ *
+ * @author egan
+ *
+ */
+ @JSONField(name = "admin_area_1")
+ private String adminArea1;
+
+ public String adminArea1() {
+ return adminArea1;
+ }
+
+ public AddressPortable adminArea1(String adminArea1) {
+ this.adminArea1 = adminArea1;
+ return this;
+ }
+
+ /**
+ * A city, town, or village. Smaller than `admin_area_level_1`.
+ */
+ @JSONField(name = "admin_area_2")
+ private String adminArea2;
+
+ public String adminArea2() {
+ return adminArea2;
+ }
+
+ public AddressPortable adminArea2(String adminArea2) {
+ this.adminArea2 = adminArea2;
+ return this;
+ }
+
+ /**
+ * A sub-locality, suburb, neighborhood, or district. Smaller than `admin_area_level_2`. Value is:
+ */
+ @JSONField(name = "admin_area_3")
+ private String adminArea3;
+
+ public String adminArea3() {
+ return adminArea3;
+ }
+
+ public AddressPortable adminArea3(String adminArea3) {
+ this.adminArea3 = adminArea3;
+ return this;
+ }
+
+ /**
+ * The neighborhood, ward, or district. Smaller than `admin_area_level_3` or `sub_locality`. Value is:
+ */
+ @JSONField(name = "admin_area_4")
+ private String adminArea4;
+
+ public String adminArea4() {
+ return adminArea4;
+ }
+
+ public AddressPortable adminArea4(String adminArea4) {
+ this.adminArea4 = adminArea4;
+ return this;
+ }
+
+ /**
+ * REQUIRED
+ * The [two-character ISO 3166-1 code](/docs/integration/direct/rest/country-codes/) that identifies the country or region.Note: The country code for Great Britain is
+ */
+ @JSONField(name = "country_code")
+ private String countryCode;
+
+ public String countryCode() {
+ return countryCode;
+ }
+
+ public AddressPortable countryCode(String countryCode) {
+ this.countryCode = countryCode;
+ return this;
+ }
+
+ /**
+ * The postal code, which is the zip code or equivalent. Typically required for countries with a postal code or an equivalent. See [postal code](https://en.wikipedia.org/wiki/Postal_code).
+ */
+ @JSONField(name = "postal_code")
+ private String postalCode;
+
+ public String postalCode() {
+ return postalCode;
+ }
+
+ public AddressPortable postalCode(String postalCode) {
+ this.postalCode = postalCode;
+ return this;
+ }
+
+ public String getAddressLine1() {
+ return addressLine1;
+ }
+
+ public void setAddressLine1(String addressLine1) {
+ this.addressLine1 = addressLine1;
+ }
+
+ public String getAddressLine2() {
+ return addressLine2;
+ }
+
+ public void setAddressLine2(String addressLine2) {
+ this.addressLine2 = addressLine2;
+ }
+
+ public String getAddressLine3() {
+ return addressLine3;
+ }
+
+ public void setAddressLine3(String addressLine3) {
+ this.addressLine3 = addressLine3;
+ }
+
+ public String getAdminArea1() {
+ return adminArea1;
+ }
+
+ public void setAdminArea1(String adminArea1) {
+ this.adminArea1 = adminArea1;
+ }
+
+ public String getAdminArea2() {
+ return adminArea2;
+ }
+
+ public void setAdminArea2(String adminArea2) {
+ this.adminArea2 = adminArea2;
+ }
+
+ public String getAdminArea3() {
+ return adminArea3;
+ }
+
+ public void setAdminArea3(String adminArea3) {
+ this.adminArea3 = adminArea3;
+ }
+
+ public String getAdminArea4() {
+ return adminArea4;
+ }
+
+ public void setAdminArea4(String adminArea4) {
+ this.adminArea4 = adminArea4;
+ }
+
+ public String getCountryCode() {
+ return countryCode;
+ }
+
+ public void setCountryCode(String countryCode) {
+ this.countryCode = countryCode;
+ }
+
+ public String getPostalCode() {
+ return postalCode;
+ }
+
+ public void setPostalCode(String postalCode) {
+ this.postalCode = postalCode;
+ }
+}
diff --git a/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/ApplicationContext.java b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/ApplicationContext.java
new file mode 100644
index 0000000..53118d7
--- /dev/null
+++ b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/ApplicationContext.java
@@ -0,0 +1,147 @@
+package com.egzosn.pay.paypal.v2.bean.order;
+
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+public class ApplicationContext {
+
+ /**
+ * 该标签将覆盖PayPal网站上PayPal帐户中的公司名称
+ */
+ @JSONField(name = "brand_name")
+ private String brandName;
+
+ @JSONField(name = "cancel_url")
+ private String cancelUrl;
+ /**
+ * LOGIN。当客户单击PayPal Checkout时,客户将被重定向到页面以登录PayPal并批准付款。
+ * BILLING。当客户单击PayPal Checkout时,客户将被重定向到一个页面,以输入信用卡或借记卡以及完成购买所需的其他相关账单信息
+ * NO_PREFERENCE。当客户单击“ PayPal Checkout”时,将根据其先前的交互方式将其重定向到页面以登录PayPal并批准付款,或重定向至页面以输入信用卡或借记卡以及完成购买所需的其他相关账单信息使用PayPal。
+ * 默认值:NO_PREFERENCE
+ */
+ @JSONField(name = "landing_page")
+ private String landingPage = "NO_PREFERENCE";
+
+
+ @JSONField(name = "return_url")
+ private String returnUrl;
+ /**
+ * GET_FROM_FILE。使用贝宝网站上客户提供的送货地址。
+ * NO_SHIPPING。从PayPal网站编辑送货地址。推荐用于数字商品
+ * SET_PROVIDED_ADDRESS。使用商家提供的地址。客户无法在PayPal网站上更改此地址
+ */
+ @JSONField(name = "shipping_preference")
+ private String shippingPreference = "NO_SHIPPING";
+ /**
+ * CONTINUE。将客户重定向到PayPal付款页面后,将出现“ 继续”按钮。当结帐流程启动时最终金额未知时,请使用此选项,并且您想将客户重定向到商家页面而不处理付款。
+ * PAY_NOW。将客户重定向到PayPal付款页面后,出现“ 立即付款”按钮。当启动结帐时知道最终金额并且您要在客户单击“ 立即付款”时立即处理付款时,请使用此选项。
+ */
+ @JSONField(name = "user_action")
+ private String userAction = "CONTINUE";
+
+ public ApplicationContext() {
+ }
+
+
+ public String brandName() {
+ return brandName;
+ }
+
+ public ApplicationContext brandName(String brandName) {
+ this.brandName = brandName;
+ return this;
+ }
+
+ public String cancelUrl() {
+ return this.cancelUrl;
+ }
+
+ public ApplicationContext cancelUrl(String cancelUrl) {
+ this.cancelUrl = cancelUrl;
+ return this;
+ }
+
+ public String landingPage() {
+ return this.landingPage;
+ }
+
+ public ApplicationContext landingPage(String landingPage) {
+ this.landingPage = landingPage;
+ return this;
+ }
+
+ public String returnUrl() {
+ return this.returnUrl;
+ }
+
+ public ApplicationContext returnUrl(String returnUrl) {
+ this.returnUrl = returnUrl;
+ return this;
+ }
+
+ public String shippingPreference() {
+ return this.shippingPreference;
+ }
+
+ public ApplicationContext shippingPreference(String shippingPreference) {
+ this.shippingPreference = shippingPreference;
+ return this;
+ }
+
+ public String userAction() {
+ return this.userAction;
+ }
+
+ public ApplicationContext userAction(String userAction) {
+ this.userAction = userAction;
+ return this;
+ }
+
+ public String getBrandName() {
+ return brandName;
+ }
+
+ public void setBrandName(String brandName) {
+ this.brandName = brandName;
+ }
+
+ public String getCancelUrl() {
+ return cancelUrl;
+ }
+
+ public void setCancelUrl(String cancelUrl) {
+ this.cancelUrl = cancelUrl;
+ }
+
+ public String getLandingPage() {
+ return landingPage;
+ }
+
+ public void setLandingPage(String landingPage) {
+ this.landingPage = landingPage;
+ }
+
+ public String getReturnUrl() {
+ return returnUrl;
+ }
+
+ public void setReturnUrl(String returnUrl) {
+ this.returnUrl = returnUrl;
+ }
+
+ public String getShippingPreference() {
+ return shippingPreference;
+ }
+
+ public void setShippingPreference(String shippingPreference) {
+ this.shippingPreference = shippingPreference;
+ }
+
+ public String getUserAction() {
+ return userAction;
+ }
+
+ public void setUserAction(String userAction) {
+ this.userAction = userAction;
+ }
+}
diff --git a/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/Money.java b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/Money.java
new file mode 100644
index 0000000..1ed4274
--- /dev/null
+++ b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/Money.java
@@ -0,0 +1,37 @@
+package com.egzosn.pay.paypal.v2.bean.order;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+public class Money {
+ @JSONField(name = "currency_code")
+ private String currencyCode;
+ @JSONField(name = "value")
+ private String value;
+
+ public String getCurrencyCode() {
+ return currencyCode;
+ }
+
+ public void setCurrencyCode(String currencyCode) {
+ this.currencyCode = currencyCode;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public Money currencyCode(String currencyCode) {
+ this.currencyCode = currencyCode;
+ return this;
+ }
+
+
+ public Money value(String value) {
+ this.value = value;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/Name.java b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/Name.java
new file mode 100644
index 0000000..f86d543
--- /dev/null
+++ b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/Name.java
@@ -0,0 +1,174 @@
+package com.egzosn.pay.paypal.v2.bean.order;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * The name of the party.
+ */
+public class Name {
+
+ // Required default constructor
+ public Name() {
+ }
+
+ /**
+ * DEPRECATED. The party's alternate name. Can be a business name, nickname, or any other name that cannot be split into first, last name. Required when the party is a business.
+ */
+ @JSONField(name = "alternate_full_name")
+ private String alternateFullName;
+
+ public String alternateFullName() {
+ return alternateFullName;
+ }
+
+ public Name alternateFullName(String alternateFullName) {
+ this.alternateFullName = alternateFullName;
+ return this;
+ }
+
+ /**
+ * When the party is a person, the party's full name.
+ */
+ @JSONField(name = "full_name")
+ private String fullName;
+
+ public String fullName() {
+ return fullName;
+ }
+
+ public Name fullName(String fullName) {
+ this.fullName = fullName;
+ return this;
+ }
+
+ /**
+ * When the party is a person, the party's given, or first, name.
+ */
+ @JSONField(name = "given_name")
+ private String givenName;
+
+ public String givenName() {
+ return givenName;
+ }
+
+ public Name givenName(String givenName) {
+ this.givenName = givenName;
+ return this;
+ }
+
+ /**
+ * When the party is a person, the party's middle name. Use also to store multiple middle names including the patronymic, or father's, middle name.
+ */
+ @JSONField(name = "middle_name")
+ private String middleName;
+
+ public String middleName() {
+ return middleName;
+ }
+
+ public Name middleName(String middleName) {
+ this.middleName = middleName;
+ return this;
+ }
+
+ /**
+ * The prefix, or title, to the party's name.
+ */
+ @JSONField(name = "prefix")
+ private String prefix;
+
+ public String prefix() {
+ return prefix;
+ }
+
+ public Name prefix(String prefix) {
+ this.prefix = prefix;
+ return this;
+ }
+
+ /**
+ * The suffix for the party's name.
+ */
+ @JSONField(name = "suffix")
+ private String suffix;
+
+ public String suffix() {
+ return suffix;
+ }
+
+ public Name suffix(String suffix) {
+ this.suffix = suffix;
+ return this;
+ }
+
+ /**
+ * When the party is a person, the party's surname or family name. Also known as the last name. Required when the party is a person. Use also to store multiple surnames including the matronymic, or mother's, surname.
+ */
+ @JSONField(name = "surname")
+ private String surname;
+
+ public String surname() {
+ return surname;
+ }
+
+ public Name surname(String surname) {
+ this.surname = surname;
+ return this;
+ }
+
+ public String getAlternateFullName() {
+ return alternateFullName;
+ }
+
+ public void setAlternateFullName(String alternateFullName) {
+ this.alternateFullName = alternateFullName;
+ }
+
+ public String getFullName() {
+ return fullName;
+ }
+
+ public void setFullName(String fullName) {
+ this.fullName = fullName;
+ }
+
+ public String getGivenName() {
+ return givenName;
+ }
+
+ public void setGivenName(String givenName) {
+ this.givenName = givenName;
+ }
+
+ public String getMiddleName() {
+ return middleName;
+ }
+
+ public void setMiddleName(String middleName) {
+ this.middleName = middleName;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String getSuffix() {
+ return suffix;
+ }
+
+ public void setSuffix(String suffix) {
+ this.suffix = suffix;
+ }
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+}
diff --git a/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/OrderRequest.java b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/OrderRequest.java
new file mode 100644
index 0000000..7b75492
--- /dev/null
+++ b/pay-java-paypal/src/main/java/com/egzosn/pay/paypal/v2/bean/order/OrderRequest.java
@@ -0,0 +1,43 @@
+package com.egzosn.pay.paypal.v2.bean.order;
+
+import java.util.List;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+public class OrderRequest {
+ @JSONField(name = "application_context")
+ private ApplicationContext applicationContext;
+ @JSONField(name = "intent")
+ private String checkoutPaymentIntent;
+
+ @JSONField(name =
+ "purchase_units"
+ )
+ private ListGB and not UK as used in the top-level domain names for that country. Use the `C2` country code for China worldwide for comparable uncontrolled price (CUP) method, bank card, and cross-border transactions.