Passed
Push — main ( 1246ad...d1c484 )
by Iain
06:09
created

createPaymentDetailsFromToken()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 13
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 21
rs 9.8333
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright Iain Cambridge 2020-2023.
7
 *
8
 * Use of this software is governed by the Business Source License included in the LICENSE file and at https://getparthenon.com/docs/next/license.
9
 *
10
 * Change Date: TBD ( 3 years after 2.2.0 release )
11
 *
12
 * On the date above, in accordance with the Business Source License, use of this software will be governed by the open source license specified in the LICENSE file.
13
 */
14
15
namespace Parthenon\Billing\PaymentMethod;
16
17
use Obol\Model\CardDetails;
18
use Obol\Model\Customer as ObolCustomer;
19
use Obol\Provider\ProviderInterface;
20
use Parthenon\Billing\Entity\CustomerInterface;
21
use Parthenon\Billing\Entity\PaymentMethod;
22
use Parthenon\Billing\Factory\PaymentDetailsFactoryInterface;
23
use Parthenon\Billing\Obol\CustomerConverterInterface;
24
use Parthenon\Billing\Repository\CustomerRepositoryInterface;
25
use Parthenon\Billing\Repository\PaymentMethodRepositoryInterface;
26
27
class FrontendAddProcessor implements FrontendAddProcessorInterface
28
{
29
    public function __construct(
30
        private ProviderInterface $provider,
31
        private CustomerRepositoryInterface $customerRepository,
32
        private CustomerConverterInterface $customerConverter,
33
        private PaymentDetailsFactoryInterface $paymentDetailsFactory,
34
        private PaymentMethodRepositoryInterface $paymentDetailsRepository,
35
    ) {
36
    }
37
38
    public function startTokenProcess(CustomerInterface $customer): string
39
    {
40
        $billingDetails = $this->customerConverter->convertToBillingDetails($customer);
41
        if (!$customer->hasExternalCustomerReference()) {
42
            $obolCustomer = new ObolCustomer();
43
            $obolCustomer->setEmail($customer->getBillingEmail());
44
            $obolCustomer->setAddress($billingDetails->getAddress());
45
            $customerCreation = $this->provider->customers()->create($obolCustomer);
46
47
            $customer->setExternalCustomerReference($customerCreation->getReference());
48
            $customer->setPaymentProviderDetailsUrl($customerCreation->getDetailsUrl());
49
        }
50
51
        $tokenData = $this->provider->payments()->startFrontendCreateCardOnFile($billingDetails);
52
        if ($tokenData->hasCustomerCreation()) {
53
            $customer->setPaymentProviderDetailsUrl($tokenData->getCustomerCreation()->getDetailsUrl());
54
            $customer->setExternalCustomerReference($tokenData->getCustomerReference());
55
        }
56
        $this->customerRepository->save($customer);
57
58
        return $tokenData->getToken();
59
    }
60
61
    public function createPaymentDetailsFromToken(CustomerInterface $customer, string $token): PaymentMethod
62
    {
63
        $billingDetails = $this->customerConverter->convertToBillingDetails($customer);
64
        $billingDetails->setCardDetails(new CardDetails());
65
        $billingDetails->getCardDetails()->setToken($token);
66
67
        $response = $this->provider->payments()->createCardOnFile($billingDetails);
68
        $cardFile = $response->getCardFile();
69
        $paymentDetails = $this->paymentDetailsFactory->buildFromCardFile($customer, $cardFile, $this->provider->getName());
70
71
        if ($response->hasCustomerCreation()) {
72
            $customer->setPaymentProviderDetailsUrl($response->getCustomerCreation()->getDetailsUrl());
73
            $customer->setExternalCustomerReference($response->getCustomerReference());
0 ignored issues
show
Bug introduced by
The method getCustomerReference() does not exist on Obol\Model\CardOnFileResponse. Did you maybe mean getCustomerCreation()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
            $customer->setExternalCustomerReference($response->/** @scrutinizer ignore-call */ getCustomerReference());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
74
        }
75
76
        if ($paymentDetails->isDefaultPaymentOption()) {
77
            $this->paymentDetailsRepository->markAllCustomerMethodsAsNotDefault($customer);
78
        }
79
        $this->paymentDetailsRepository->save($paymentDetails);
80
81
        return $paymentDetails;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $paymentDetails returns the type Parthenon\Billing\Entity\PaymentDetails which is incompatible with the type-hinted return Parthenon\Billing\Entity\PaymentMethod.
Loading history...
82
    }
83
}
84