PayPal::getPaymentUrl()   A
last analyzed

Complexity

Conditions 2
Paths 3

Size

Total Lines 40
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 29
nc 3
nop 1
dl 0
loc 40
rs 9.456
c 0
b 0
f 0
1
<?php
2
3
namespace App\PaymentProvider;
4
5
use App\Purchase;
6
use PayPal\Exception\PayPalConnectionException;
7
8
use PayPal\Rest\ApiContext;
9
use PayPal\Auth\OAuthTokenCredential;
10
11
use PayPal\Api\Payer;
12
use PayPal\Api\Amount;
13
use PayPal\Api\Transaction;
14
use PayPal\Api\RedirectUrls;
15
use PayPal\Api\Payment;
16
use Illuminate\Support\Facades\Log;
17
use App\Exceptions\PaymentProviderException;
18
use PayPal\Api\PaymentOptions;
19
use PayPal\Api\PaymentExecution;
20
use Illuminate\Support\Facades\App;
21
22
23
/**
24
 * Class to process requests and responses to and from PayPal
25
 * 
26
 * Find docs @ https://github.com/paypal/PayPal-PHP-SDK
27
 */
28
class PayPal
29
{
30
    /**
31
     * API-Object; initialized by constructor
32
     */
33
    protected $apiContext;
34
35
36
    /**
37
     * @param string $clientId ClientID for the shops paypal REST endpoint
38
     * @param string $clientSecret Secret for the shops paypal REST endpoint
39
     * @return void
40
     */
41
    public function __construct($clientId, $clientSecret)
42
    {
43
        $this->apiContext = new ApiContext(
44
            new OAuthTokenCredential( $clientId, $clientSecret)
45
        );
46
47
        if(App::environment('prod')) {
48
            $this->apiContext->setConfig([
49
                'mode' => 'live'
50
            ]);
51
        }
52
    }
53
54
    /**
55
     * Contains full logic and switches in code for the correct payment method
56
     * 
57
     * @throws PaymentProviderException on errors
58
     */
59
    public function getPaymentUrl(Purchase $purchase)
60
    {
61
        $payer = new Payer();
62
        $payer->setPaymentMethod('paypal');
63
64
        $amount = new Amount();
65
        $amount->setTotal($purchase->total());
66
        $amount->setCurrency('EUR');
67
68
        $paymentOptions = new PaymentOptions();
69
        $paymentOptions->setAllowedPaymentMethod('INSTANT_FUNDING_SOURCE');
70
71
        $transaction = new Transaction();
72
        $transaction->setAmount($amount);
73
        $transaction->setPaymentOptions($paymentOptions);
74
        $transaction->setDescription('#' . $purchase->id . ' Ticket purchase');
75
        $transaction->setInvoiceNumber($purchase->id);
76
77
        $redirectUrls = new RedirectUrls();
78
        $redirectUrls
79
            ->setReturnUrl(route('ts.payment.payPalExec', [
80
                'purchase' => $purchase->random_id,
81
                'secret' => $purchase->payment_secret
82
            ]))
83
            ->setCancelUrl(route('ts.payment.aborted', ['purchase' => $purchase->random_id]));
84
85
        $payment = new Payment();
86
        $payment->setIntent('sale')
87
            ->setPayer($payer)
88
            ->setTransactions(array($transaction))
89
            ->setRedirectUrls($redirectUrls);
90
91
        try {
92
            $payment->create($this->apiContext);
93
            return $payment->getApprovalLink();
94
        } catch (PayPalConnectionException $ex) {
95
            // This will print the detailed information on the exception.
96
            //REALLY HELPFUL FOR DEBUGGING
97
            Log::error($ex->getData());
98
            throw new PaymentProviderException('PayPal has errors...');
99
        }
100
    }
101
102
    /**
103
     * Excute payment after user returns from PayPal
104
     * 
105
     * @throws PaymentProviderException if something goes wrong
106
     */
107
    public function executePayment($paymentId, $payerId)
108
    {
109
        $payment = Payment::get($paymentId, $this->apiContext);
110
111
        $execution = new PaymentExecution();
112
        $execution->setPayerId($payerId);
113
114
        try {
115
            // Execute the payment
116
            $payment->execute($execution, $this->apiContext);
117
            try {
118
                $payment = Payment::get($paymentId, $this->apiContext);
119
            } catch (\Exception $ex) {
120
                throw new PaymentProviderException('Error on getting Payment-ID.');
121
            }
122
        } catch (\Exception $ex) {
123
            throw new PaymentProviderException('Error on executing PayPal payment.');
124
        }
125
        return $payment;
126
    }
127
}
128