授权和获取 PayPal 订单

Authorize and Capture PayPal Order

我正在尝试将 PayPal Checkout SDK 集成到我的应用程序中。

我这样创建请求:

    protected int doPaypalOrderWithCustomer(PayPalPurchase purchase, Customer customer) throws PayPalException {
        PayPalClient client = new PayPalClient();
        // Creating an order
        HttpResponse<Order> orderResponse = null;
        try{
            orderResponse = client.createCustomerOrder("Order", purchase.getTotalCheckoutCost(), 1, customer);
            String orderId = "";
            log.info("Creating Order...");
            if(orderResponse.statusCode() == 201){
                orderId = orderResponse.result().id();
                log.info("Order ID: " + orderId);
                log.info("Links:");
                for(LinkDescription link : orderResponse.result().links()){
                    log.info(link.rel() + ": " + link.href());
                    if("approve".equalsIgnoreCase(link.rel())){
                        log.info("Request Approved");
                        ServletActionContext.getResponse().sendRedirect(link.href());
                        break;
                    }// end if
                }// end for
            }// end if
            log.info("Created Successfully");
        }catch(Exception e){
            throw new PayPalException("Creating a PayPal order failed. Message is: " + e.getMessage(), e);
        }finally{
            if(null != orderResponse){
                log.info("Order response status code is: " + String.valueOf(orderResponse.statusCode()));
            }else{
                log.info("Order response is null.");
            }// end if/else
        }// end try/catch/finally
        return orderResponse.statusCode();
    }// end doPaypalOrderWithCustomer
       

第二种方法是:

    public HttpResponse<Order> createCustomerOrder(String desc, double cost, int quantity, Customer customer) throws Exception {
        log.debug("Entering createCustomerOrder");
        if(log.isDebugEnabled()){
            log.debug("Method to create order with complete payload");
            log.debug("Entry parameters are: desc=" + String.valueOf(desc) + ", cost=" + String.valueOf(cost) + ", quantity=" + String.valueOf(quantity) + ", Customer=" + String.valueOf(customer));
        }// end if
        double individualCost = cost / quantity;
        NumberFormat format = NumberFormat.getNumberInstance();
        format.setMaximumFractionDigits(2);
        format.setMinimumFractionDigits(2);
        OrdersCreateRequest request = new OrdersCreateRequest();
        request.header("prefer", "return=representation");
        OrderRequest orderRequest = new OrderRequest();
        orderRequest.checkoutPaymentIntent("CAPTURE");
        Payer payer = new Payer();
        payer.email(customer.getEmail());
        PhoneWithType phoneWithType = new PhoneWithType();
        Phone phone = new Phone();
        String phoneNumber = customer.getPhoneNo().replace("(", "");
        phoneNumber = customer.getPhoneNo().replace(")", "");
        phoneNumber = customer.getPhoneNo().replace("-", "");
        phoneNumber = phoneNumber.replaceAll("\D+", "");
        phone.nationalNumber(phoneNumber);
        phoneWithType.phoneNumber(phone);
        payer.phoneWithType(phoneWithType);
        orderRequest.payer(payer);
        ApplicationContext applicationContext = new ApplicationContext() //
                .brandName("LLC")//
                .landingPage("BILLING")//
                .cancelUrl(bundle.getString("RESPONSE_URL") + "?t=c")//
                .returnUrl(bundle.getString("RESPONSE_URL") + "?t=r")//
                .userAction("PAY_NOW").shippingPreference("NO_SHIPPING");
        log.info("Method call to orderRequest.applicationContext(applicationContext)");
        orderRequest.applicationContext(applicationContext);
        List<PurchaseUnitRequest> purchaseUnitRequests = new ArrayList<>();
        PurchaseUnitRequest purchaseUnitRequest = new PurchaseUnitRequest()//
                .referenceId("PUHF")//
                .description("Digital Content")//
                .customId("CUST-DigitalContent")//
                .softDescriptor("DigitalContent")//
                .amountWithBreakdown(new AmountWithBreakdown()//
                        .currencyCode("USD")//
                        .value(format.format(cost))//
                        .amountBreakdown(new AmountBreakdown()//
                                .itemTotal(new Money()//
                                        .currencyCode("USD")//
                                        .value(format.format(cost)))//
                                .shipping(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))//
                                .handling(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))//
                                .taxTotal(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))//
                                .shippingDiscount(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))))
                .items(new ArrayList<Item>(){
                    private static final long serialVersionUID = 1L;
                    {
                        add(new Item()//
                                .name(desc)//
                                .description(desc)//
                                .sku("sku01").//
                        unitAmount(new Money()//
                                .currencyCode("USD")//
                                .value(format.format(individualCost)))//
                                .tax(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))//
                                .quantity(String.valueOf(quantity))//
                                .category("DIGITAL_GOODS"));
                    }
                });
        purchaseUnitRequests.add(purchaseUnitRequest);
        orderRequest.purchaseUnits(purchaseUnitRequests);
        request.requestBody(orderRequest);
        HttpResponse<Order> response = client().execute(request);
        if(response.statusCode() == 201){
            for(com.paypal.orders.LinkDescription link : response.result().links()){
                log.info(link.rel() + ": " + link.href() + "; Call Type: " + link.method());
            }// end for
            log.info("Total Amount: " + response.result().purchaseUnits().get(0).amountWithBreakdown().currencyCode() + " " + response.result().purchaseUnits().get(0).amountWithBreakdown().value());
            log.info(new JSONObject(new Json().serialize(response.result())).toString(4));
        }// end if
        if(log.isDebugEnabled()){
            log.debug("Return value is: response=" + String.valueOf(response));
        }// end if
        log.debug("Exiting createCustomerOrder");
        return response;
    }// end createCustomerOrder

使用沙箱,我被转发到 PayPal。我按照步骤支付购买费用。我知道我必须捕获订单,但我不知道如何。从 PAYPAL 重定向后,我将购买保存到数据库中。问题是 PAYPAL 正在转发到我的网站,就像付款一样。而实际上 PAYPAL 中没有任何指示付款的内容。

我目前正在使用 checkout.jar

有没有不用 javascript 的方法?我不想完成应用程序的重组。

付款未在 PayPal 完成。对于重定向集成,在 return 到您的站点之后,您需要捕获订单并显示结果(success/thank 您,或再次 failure/try)。 URL 将包含捕获所需的 ID。


当前集成不使用任何重定向。完全没有。 (对于使用这种集成模式的旧网站,API 响应具有重定向 URL)

相反,在您的服务器上分别为创建订单和捕获订单 API 创建两条路线。捕获路由必须将 id 作为输入(路径或正文参数),因此它知道要捕获哪个。两条路线都应该 return/output 只有 JSON 数据,没有 HTML 或文本。

将这两条路线与以下批准流程配对:https://developer.paypal.com/demo/checkout/#/pattern/server

经过数周的反复试验,我终于让 js 免费 PayPal 实现正常工作。 完成 PayPal 交易需要 3 个步骤。

步骤 1. 创建订单。此步骤会将客户带到 PayPal 网站。

Class 变量:private PayPalClient client = new PayPalClient(); private PayPalHttpClient hClient = new PayPalHttpClient(client.getEnvironment());

protected int doPaypalOrderWithCustomer(PayPalPurchase purchase, Customer customer) throws PayPalException {
    log.info("ENVIRONMENT: " + String.valueOf(client.getEnvironment()));
    orderResponse = null;
    try{
        orderId = "";
        // Creating an order payload
        OrdersCreateRequest request = new OrdersCreateRequest();
        // Build PayPal Request Body
        request = client.createCustomerOrder("Company Order", purchase.getTotalCheckoutCost(), 1, customer);
        // Create Order
        orderResponse = hClient.execute(request);
        log.info("Creating Order...");
        if(orderResponse.statusCode() == 201){
        log.info("Order with Complete Payload: ");
        log.info("Status Code: " + orderResponse.statusCode());
        log.info("Status: " + orderResponse.result().status());
        log.info("Order ID: " + orderResponse.result().id());
        log.info("Intent: " + orderResponse.result().checkoutPaymentIntent());
        log.info("Links: ");
        for(LinkDescription link : orderResponse.result().links()){
            log.info("\t" + link.rel() + ": " + link.href() + "\tCall Type: " + link.method());
        }// end for
        log.info("Total Amount: " + orderResponse.result().purchaseUnits().get(0).amountWithBreakdown().currencyCode() + " " + orderResponse.result().purchaseUnits().get(0).amountWithBreakdown().value());
        log.info("Full response body:");
        log.info("Authorized Successfully\n");
        orderId = orderResponse.result().id();
        log.info("PURCHASE UNIT ORDER ID: " + orderId);
        for(LinkDescription link : orderResponse.result().links()){
            String check = link.rel();
            log.info(link.rel() + ": " + link.href());
            if(check.equalsIgnoreCase("approve")){
            log.info("Request Approved");
            ServletActionContext.getResponse().sendRedirect(link.href());
            break;
            }else{
            log.info("CURRENT LINK: " + link.rel() + " NOT APPROVED");
            }// end if
        }// end for
        sessionMap.put("orderId", orderId);
        }// end if
        log.info("Created Successfully");
    }catch(Exception e){
        throw new PayPalException("Creating a PayPal order failed. Message is: " + e.getMessage(), e);
    }finally{
        if(null != orderResponse){
        log.info("Order response status code is: " + String.valueOf(orderResponse.statusCode()));
        }else{
        log.info("Order response is null.");
        }// end if/else
    }// end try/catch/finally

    return orderResponse.statusCode();
}// end doPaypalOrderWithCustomer

public OrdersCreateRequest createCustomerOrder(String desc, double cost, int quantity, Customer customer) throws Exception {
        log.debug("Entering createCustomerOrder");
        if(log.isDebugEnabled()){
            log.debug("Method to create order with complete payload");
            log.debug("Entry parameters are: desc=" + String.valueOf(desc) + ", cost=" + String.valueOf(cost) + ", quantity=" + String.valueOf(quantity) + ", Customer=" + String.valueOf(customer));
        }// end if
        double individualCost = cost / quantity;
        NumberFormat format = NumberFormat.getNumberInstance();
        format.setMaximumFractionDigits(2);
        format.setMinimumFractionDigits(2);
        OrdersCreateRequest request = new OrdersCreateRequest();
        request.header("prefer", "return=representation");
        OrderRequest orderRequest = new OrderRequest();
        orderRequest.checkoutPaymentIntent("AUTHORIZE");// This must be AUTHORIZE for the 3 step process
        Payer payer = new Payer();
        payer.email(customer.getEmail());
        PhoneWithType phoneWithType = new PhoneWithType();
        Phone phone = new Phone();
        String phoneNumber = customer.getPhoneNo().replace("(", "");
        phoneNumber = customer.getPhoneNo().replace(")", "");
        phoneNumber = customer.getPhoneNo().replace("-", "");
        phoneNumber = phoneNumber.replaceAll("\D+", "");
        phone.nationalNumber(phoneNumber);
        phoneWithType.phoneNumber(phone);
        payer.phoneWithType(phoneWithType);
        orderRequest.payer(payer);
        ApplicationContext applicationContext = new ApplicationContext() //
                .brandName("Company, LLC")//
                .landingPage("BILLING")//
                .cancelUrl(bundle.getString("RESPONSE_URL") + "?t=c")//
                .returnUrl(bundle.getString("RESPONSE_URL") + "?t=r")//
                .userAction("CONTINUE").shippingPreference("NO_SHIPPING");
        orderRequest.applicationContext(applicationContext);
        List<PurchaseUnitRequest> purchaseUnitRequests = new ArrayList<>();
        PurchaseUnitRequest purchaseUnitRequest = new PurchaseUnitRequest()//
                .referenceId("PUHF")//
                .description("Digital Content")//
                .customId("CUST-DigitalContent")//
                .softDescriptor("DigitalContent")//
                .amountWithBreakdown(new AmountWithBreakdown()//
                        .currencyCode("USD")//
                        .value(format.format(cost))//
                        .amountBreakdown(new AmountBreakdown()//
                                .itemTotal(new Money()//
                                        .currencyCode("USD")//
                                        .value(format.format(cost)))//
                                .shipping(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))//
                                .handling(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))//
                                .taxTotal(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))//
                                .shippingDiscount(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))))
                .items(new ArrayList<Item>(){
                    private static final long serialVersionUID = 1L;
                    {
                        add(new Item()//
                                .name(desc)//
                                .description(desc)//
                                .sku("sku01").//
                        unitAmount(new Money()//
                                .currencyCode("USD")//
                                .value(format.format(individualCost)))//
                                .tax(new Money()//
                                        .currencyCode("USD")//
                                        .value("0.00"))//
                                .quantity(String.valueOf(quantity))//
                                .category("DIGITAL_GOODS"));
                    }
                }).shippingDetail(new ShippingDetail()//
                        .name(new Name()//
                                .fullName(customer.getFirstNm() + " " + customer.getLastNm()))//
                        .addressPortable(new AddressPortable()//
                                .addressLine1(customer.getAddress())//
                                .addressLine2(customer.getAddress2())//
                                .adminArea1(customer.getState())//
                                .adminArea2(customer.getCity())//
                                .postalCode(customer.getZipCode())//
                                .countryCode("US")));
        purchaseUnitRequests.add(purchaseUnitRequest);
        orderRequest.purchaseUnits(purchaseUnitRequests);
        request.requestBody(orderRequest);
        HttpResponse<Order> response = client().execute(request);
        if(response.statusCode() == 201){
            for(com.paypal.orders.LinkDescription link : response.result().links()){
                log.info(link.rel() + ": " + link.href() + "; Call Type: " + link.method());
            }// end for
            log.info("Total Amount: " + response.result().purchaseUnits().get(0).amountWithBreakdown().currencyCode() + " " + response.result().purchaseUnits().get(0).amountWithBreakdown().value());
            log.info(new JSONObject(new Json().serialize(response.result())).toString(4));
        }// end if
        if(log.isDebugEnabled()){
            log.debug("Return value is: response=" + String.valueOf(request));
        }// end if
        log.debug("Exiting createCustomerOrder");
        return request;
    }// end createCustomerOrder

第 2 步:我们批准订单并从 PayPal 获取授权订单 ID。

public String approve() throws Exception {
        log.debug("Entering approve method.");
        log.trace("This method is used to approce purchases Post PayPal redirect.");
        log.info("Authorizing Order...");
        HttpServletRequest request = ServletActionContext.getRequest();
        String cancel = request.getParameter("t");
        log.info("Parameter being returned from PayPal: " + String.valueOf(cancel));
        if(cancel.equalsIgnoreCase("c")){
            payPalCancel = true;
            if(null != sessionMap.get("purchase")){
                sessionMap.remove("purchase");
            }// end if
            if(null != sessionMap.get("cartCount")){
                sessionMap.put("cartCount", 0);
            }// end if
            setCartCount(0);
            if(null != sessionMap.get("images")){
                sessionMap.remove("images");
            }// end if
            setPayPalCancel(true);
            return INPUT;
        }else{
            if(null != sessionMap.get("orderId")){
                orderId = (String) sessionMap.get("orderId");
            }// end if
            log.info("Order ID: " + String.valueOf(orderId));
            OrdersAuthorizeRequest orderAuthorizeRequest = new OrdersAuthorizeRequest(orderId);
            orderAuthorizeRequest.requestBody(new OrderRequest());
            orderResponse = hClient.execute(orderAuthorizeRequest);
            if(orderResponse.statusCode() == 201){
                authOrderId = orderResponse.result().purchaseUnits().get(0).payments().authorizations().get(0).id();
                log.info("AUTHORIZED ORDER ID: " + authOrderId);
            }// end if
            sessionMap.put("authOrderId", authOrderId);
            log.debug("Exiting approve");
        }// end if/else
        return SUCCESS;
}// end approve

第 3 步:作为开发人员,我们必须捕获已批准的订单。这是最后一步。

public String capture() throws Exception {
    log.debug("Entering capture method.");
    log.trace("This method is used to save capture Payment.");
    // Capturing authorized order
    if(null != sessionMap.get("authOrderId")){
        authOrderId = (String) sessionMap.get("authOrderId");
    }// end if
    log.info("Authorized Order ID: " + String.valueOf(authOrderId));
    log.info("Capturing Order...");
    setCaptured(true);
    HttpResponse<Capture> captureOrderResponse = new CaptureOrder().captureOrder(authOrderId, true);
    if(captureOrderResponse.statusCode() == 201){
        log.info("Captured Successfully");
        log.info("Status Code: " + captureOrderResponse.statusCode());
        log.info("Status: " + captureOrderResponse.result().status());
        log.info("Capture ID: " + captureOrderResponse.result().id());
        log.info("Links: ");
        for(com.paypal.payments.LinkDescription link : captureOrderResponse.result().links()){
        log.info("\t" + link.rel() + ": " + link.href() + "\tCall Type: " + link.method());
        }// end for
    }// end if
    log.debug("Exiting capture");
    return SUCCESS;
}// end capture

感谢所有帮助过的人。我是新手,可能做错了什么,但我终于让它工作了。