2023-05-24

What steps should I follow to enable PayPal Advanced Credit Card Payment integration in Spring Boot app for non-PayPal account holders?

I am trying to integrate paypal advanced credit card payment, for customers who do not have a paypal account to be able to pay using their card. And I'm facing issues doing that.

I succesfuly integrated Paypal into my Spring Boot app, but only for customers with a paypal account (They are redirected and required to log into paypal before paying).

The issue here is I want get a response from Paypal and beign able to process it alongside the user's session information,

I followed tutorials leading to creating a PaymentSource instance and then setting into my orderRequest :

Card card = new Card();
        card.number(creditCard.getNumber())
            .expiry("YYYY-MM")
            .securityCode("CVV");
PaymentSource paymentSource = new PaymentSource().card(card);

But OrderRequest has no property as PaymetSource. I provide source code below, can you please help me fix this issue, or just provide me with a guide for the integration from scratch.

Thank you.


import java.net.URI;
import java.util.Arrays;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.nicanor.shakt.web.entities.CreatedOrder;
import com.paypal.api.payments.CreditCard;
import com.paypal.core.PayPalEnvironment;
import com.paypal.core.PayPalHttpClient;
import com.paypal.http.HttpResponse;
import com.paypal.orders.AmountWithBreakdown;
import com.paypal.orders.ApplicationContext;
import com.paypal.orders.Card;
import com.paypal.orders.LinkDescription;
import com.paypal.orders.Money;
import com.paypal.orders.Order;
import com.paypal.orders.OrderRequest;
import com.paypal.orders.OrdersCaptureRequest;
import com.paypal.orders.OrdersCreateRequest;
import com.paypal.orders.PaymentInstruction;
import com.paypal.orders.PaymentSource;
import com.paypal.orders.PurchaseUnitRequest;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.util.NoSuchElementException;

@Service
public class PayPalPaymentService implements PaymentService {

    private final String APPROVE_LINK_REL = "approve";

    private final PayPalHttpClient payPalHttpClient;

    public PayPalPaymentService(@Value("${paypal.clientId}") String clientId, @Value("${paypal.clientSecret}") String clientSecret) {
        payPalHttpClient = new PayPalHttpClient(new PayPalEnvironment.Sandbox(clientId, clientSecret));
    }

    @Override
    @SneakyThrows
    public CreatedOrder createOrder(Double totalAmount, URI returnUrl) {
        //STEP4 CREATE ORDER REQUEST
        final OrderRequest orderRequest = createOrderRequest(totalAmount, returnUrl);
        final OrdersCreateRequest ordersCreateRequest = new OrdersCreateRequest().requestBody(orderRequest);
        final HttpResponse<Order> orderHttpResponse = payPalHttpClient.execute(ordersCreateRequest);
        
        //STEP6 ON RECUPERE L'ORDRE, approve uri c'est l'url pour valider l'ordre sur paypal
        final Order order = orderHttpResponse.result();
        LinkDescription approveUri = extractApprovalLink(order);
        return new CreatedOrder(order.id(),URI.create(approveUri.href()));
    }

    @Override
    @SneakyThrows
    //public void captureOrder(String orderId) {
    public HttpResponse<Order> captureOrder(String orderId) {
        final OrdersCaptureRequest ordersCaptureRequest = new OrdersCaptureRequest(orderId);
        final HttpResponse<Order> httpResponse = payPalHttpClient.execute(ordersCaptureRequest);
        return httpResponse;
    }

    private OrderRequest createOrderRequest(Double totalAmount, URI returnUrl) {
        
        // Create a credit card object with the card details
        CreditCard creditCard = new CreditCard();
        creditCard.setNumber("card number");
        creditCard.setExpireMonth(1);
        creditCard.setExpireYear(2025);
        creditCard.setCvv2(123);
        creditCard.setFirstName("first name");
        creditCard.setLastName("last name");
        
        Card card = new Card();
        card.number(creditCard.getNumber())
            .expiry("YYYY-MM")
            .securityCode("CVV");
        PaymentSource paymentSource = new PaymentSource().card(card);
        
      
        
        //STEP5 TOUTES LES CONFIGS
        // Add the purchase unit to the order request object
        OrderRequest orderRequest = new OrderRequest();
        setCheckoutIntent(orderRequest);
        setPurchaseUnits(totalAmount, orderRequest, paymentSource);
        setApplicationContext(returnUrl, orderRequest);
        return orderRequest;
    }

    private OrderRequest setApplicationContext(URI returnUrl, OrderRequest orderRequest) {
        return orderRequest.applicationContext(new ApplicationContext().returnUrl(returnUrl.toString()));
    }

    private void setPurchaseUnits(Double totalAmount, OrderRequest orderRequest, PaymentSource paymentSource) {
        
        
        final PurchaseUnitRequest purchaseUnitRequest = new PurchaseUnitRequest()
                .amountWithBreakdown(new AmountWithBreakdown().currencyCode("CAD").value(totalAmount.toString()));
        orderRequest.purchaseUnits(Arrays.asList(purchaseUnitRequest));
    }

    private void setCheckoutIntent(OrderRequest orderRequest) {
        orderRequest.checkoutPaymentIntent("CAPTURE");
    }

    private LinkDescription extractApprovalLink(Order order) {
        LinkDescription approveUri = order.links().stream()
                .filter(link -> APPROVE_LINK_REL.equals(link.rel()))
                .findFirst()
                .orElseThrow(NoSuchElementException::new);
        return approveUri;
    }
    
}


No comments:

Post a Comment