Search code examples
spring-bootpaypalpaypal-sandboxpaypal-rest-sdk

How to approve a PayPal Order ID without a redirect or smart button


My purpose seems to be similar to this question posted previously how to approve an order ID

I've implemented a rest endpoint to complete order payment without using redirect link and default smart button generation

I am using sandbox environment and PayPal Server side SDK V2

So I created an order using the API OrdersCreateRequest() then I get an order ID

{
"id": "xxxxxxxxxxxxxxxx",
"status": "CREATED",
"links": [
    {
        "href": "https://api.sandbox.paypal.com/v2/checkout/orders/0XY49131JG183432Y",
        "rel": "self",
        "method": "GET"
    },
    {
        "href": "https://www.sandbox.paypal.com/checkoutnow?token=0XY49131JG183432Y",
        "rel": "approve",
        "method": "GET"
    },
    {
        "href": "https://api.sandbox.paypal.com/v2/checkout/orders/0XY49131JG183432Y",
        "rel": "update",
        "method": "PATCH"
    },
    {
        "href": "https://api.sandbox.paypal.com/v2/checkout/orders/0XY49131JG183432Y/capture",
        "rel": "capture",
        "method": "POST"
    }
]
 }

I've followed exactly the official example in the documentation, but I can't authorize the order

    @PostMapping( "payWorkerWithPaypal/{paypalWorkerEmail}/{totalAmount}")
    public Order payWorkerWithPaypal(@PathVariable("paypalWorkerEmail") String 
   
    paypalWorkerEmail,@PathVariable("totalAmount") String totalAmount) throws IOException {

    Order order = null;

    PayPalHttpClient client = new PayPalHttpClient(environment);

    OrderRequest orderRequest = new OrderRequest();

    orderRequest.checkoutPaymentIntent("CAPTURE");

    List<PurchaseUnitRequest> purchaseUnitRequests = new ArrayList<PurchaseUnitRequest>();

    PurchaseUnitRequest purchaseUnitRequest = new PurchaseUnitRequest();

     purchaseUnitRequest.amountWithBreakdown(new 
     AmountWithBreakdown().currencyCode("USD").value(totalAmount));

    Payee payee = new Payee();

    payee.email(paypalWorkerEmail);

    purchaseUnitRequest.payee(payee);

    Payer payer = new Payer();

    payer.email("outsourcingpaypal@gmail.com");

    purchaseUnitRequests.add(purchaseUnitRequest);

    orderRequest.purchaseUnits(purchaseUnitRequests);

    orderRequest.payer(payer);

    OrdersCreateRequest requestCreateOrder = new OrdersCreateRequest().requestBody(orderRequest);

    try {       
   
    HttpResponse<Order> responseOrderCreated = client.execute(requestCreateOrder);

        order = responseOrderCreated.result(); 

        System.out.println("Order ID: " + order.id());

        OrdersAuthorizeRequest requestAuthorizeRequest = new OrdersAuthorizeRequest(order.id());

        HttpResponse<Order> responseAuthorizeOrder =  client.execute(requestAuthorizeRequest);

        order = responseAuthorizeOrder.result();

        OrdersCaptureRequest requestCaptureOrder = new OrdersCaptureRequest(order.id());

        HttpResponse<Order> responseCaptureOrder =  client.execute(requestCaptureOrder);

        order = responseCaptureOrder.result();

} catch (IOException ioe) {     System.out.println(ioe.getMessage());       }        return order;
}

and I get response object with description

Payer has not yet approved the Order for payment

How do I approve the order directly with my method ?


Solution

  • Either the smart button or a redirect to the v2/checkout/orders approval_url are the only two options for a buyer to give their consent and approve a PayPal payment.

    The smart button is by far the best choice in general, due to the modern "in context" it experience it offers (keeping your site loaded in the background, and not redirecting the buyer away to a different and possibly unfamiliar page) -- as well as potentially offering several alternative payment methods depending on how you configure the button.