diff --git a/src/Builders/InvoiceBuilder.php b/src/Builders/InvoiceBuilder.php index 41dfb2a..3c23122 100644 --- a/src/Builders/InvoiceBuilder.php +++ b/src/Builders/InvoiceBuilder.php @@ -42,16 +42,32 @@ public function create(): Invoice return parent::create(); } + + /** + * Set the invoice available payment methods + * + * @param string[] $paymentMethods + * + * @return InvoiceBuilder + */ + public function setAvailablePaymentMethods(array $paymentMethods): InvoiceBuilder + { + $this->model->availablePaymentMethods = $paymentMethods; + return $this; + } + /** - * Set the invoice payment method + * Add the invoice available payment methods * * @param string $paymentMethod * * @return InvoiceBuilder */ - public function setPaymentMethod(string $paymentMethod): InvoiceBuilder + public function addAvailablePaymentMethod(string $paymentMethod): InvoiceBuilder { - $this->model->paymentMethod = $paymentMethod; + $paymentMethods = is_array($this->model->availablePaymentMethods) ? $this->model->availablePaymentMethods : []; + $paymentMethods[] = $paymentMethod; + $this->model->availablePaymentMethods = $paymentMethods; return $this; } diff --git a/src/Gateways/IuguGateway.php b/src/Gateways/IuguGateway.php index fe676a8..2c13cad 100644 --- a/src/Gateways/IuguGateway.php +++ b/src/Gateways/IuguGateway.php @@ -79,8 +79,8 @@ public function createInvoice(Invoice $invoice): Invoice } } - if (!empty($invoice->paymentMethod)) { - $iuguInvoiceData['payable_with'] = $invoice->paymentMethod; + if (!empty($invoice->availablePaymentMethods)) { + $iuguInvoiceData['payable_with'] = $invoice->availablePaymentMethods; } if (!empty($invoice->gatewayAdicionalOptions)) { @@ -89,7 +89,11 @@ public function createInvoice(Invoice $invoice): Invoice } } - if (!empty($invoice->paymentMethod) && $invoice->paymentMethod == Invoice::PAYMENT_METHOD_CREDIT_CARD) { + if ( + !empty($invoice->availablePaymentMethods) && + in_array(Invoice::PAYMENT_METHOD_CREDIT_CARD, $invoice->availablePaymentMethods) && + !empty($invoice->creditCard) + ) { if (empty($invoice->creditCard->id)) { $invoice->creditCard = $this->createCreditCard($invoice->creditCard); } @@ -390,6 +394,25 @@ private function parseInvoice($iuguInvoice, ?Invoice $invoice = null): Invoice $invoice->paymentMethod = $this->iuguToMultiPaymentPaymentMethod($iuguInvoice->payment_method); } + if (!empty(($iuguInvoice->payable_with))) { + + $payableWith = $iuguInvoice->payable_with; + if (is_string($payableWith)) { + $payableWith = [$payableWith]; + } + + foreach ($payableWith as $pm) { + $method = $this->iuguToMultiPaymentPaymentMethod($pm); + if (is_null($method) && $pm === 'all') { + $invoice->availablePaymentMethods = [ + Invoice::PAYMENT_METHOD_CREDIT_CARD, + Invoice::PAYMENT_METHOD_BANK_SLIP, + Invoice::PAYMENT_METHOD_PIX, + ]; + } + } + } + if (empty($invoice->customer)) { $invoice->customer = new Customer(); } diff --git a/src/Models/Invoice.php b/src/Models/Invoice.php index 50de333..697c7fc 100644 --- a/src/Models/Invoice.php +++ b/src/Models/Invoice.php @@ -67,6 +67,11 @@ class Invoice extends Model */ public ?string $paymentMethod = null; + /** + * @var string[]|null + */ + public ?array $availablePaymentMethods = null; + /** * @var CreditCard|null */ @@ -175,36 +180,6 @@ public function attributesExtraValidation($attributes): void if (in_array('amount', $attributes) && in_array('items', $attributes) && empty($this->amount) && empty($this->items)) { throw ModelAttributeValidationException::required($model, 'amount or items'); } - - if ( - in_array('paymentMethod', $attributes) && - !empty($this->paymentMethod) && - $this->paymentMethod == Invoice::PAYMENT_METHOD_CREDIT_CARD && - empty($this->creditCard) - ) { - throw new ModelAttributeValidationException('The `creditCard` attribute is required for credit_card payment method.'); - } - - if ( - in_array('paymentMethod', $attributes) && - !empty($this->paymentMethod) && - ( - $this->paymentMethod == Invoice::PAYMENT_METHOD_BANK_SLIP || - $this->paymentMethod == Invoice::PAYMENT_METHOD_PIX - ) && - empty($this->expiresAt) - ) { - throw new ModelAttributeValidationException('The `expiresAt` attribute is required for bank_slip or pix payment method.'); - } - - if ( - in_array('paymentMethod', $attributes) && - !empty($this->paymentMethod) && - $this->paymentMethod == Invoice::PAYMENT_METHOD_BANK_SLIP && - empty($this->customer->address) - ) { - throw new ModelAttributeValidationException('The customer address is required for bank_slip payment method'); - } } /** @@ -235,22 +210,21 @@ public function validateItemsAttribute() * @return void * @throws ModelAttributeValidationException */ - public function validatePaymentMethodAttribute() + public function validateAvailablePaymentMethodsAttribute() { - if (!in_array($this->paymentMethod, [ - Invoice::PAYMENT_METHOD_CREDIT_CARD, - Invoice::PAYMENT_METHOD_BANK_SLIP, - Invoice::PAYMENT_METHOD_PIX, - ])) { - throw ModelAttributeValidationException::invalid( - 'Invoice', - 'paymentMethod', - 'paymentMethod must be one of: ' . implode(', ', [ - Invoice::PAYMENT_METHOD_CREDIT_CARD, - Invoice::PAYMENT_METHOD_BANK_SLIP, - Invoice::PAYMENT_METHOD_PIX, - ]) - ); + $meethods = [ + self::PAYMENT_METHOD_CREDIT_CARD, + self::PAYMENT_METHOD_BANK_SLIP, + self::PAYMENT_METHOD_PIX, + ]; + + if (!is_array($this->availablePaymentMethods)) { + throw ModelAttributeValidationException::invalid('Invoice', 'availablePaymentMethods', 'availablePaymentMethods must be an array of payment methods'); + } + foreach ($this->availablePaymentMethods as $method) { + if (!in_array($method, $meethods)) { + throw ModelAttributeValidationException::invalid('Invoice', 'availablePaymentMethods', 'availablePaymentMethods must be one of: ' . implode(', ', $meethods)); + } } } diff --git a/tests/Unit/Builders/InvoiceBuilderTest.php b/tests/Unit/Builders/InvoiceBuilderTest.php index d0a3c52..7c85cdf 100644 --- a/tests/Unit/Builders/InvoiceBuilderTest.php +++ b/tests/Unit/Builders/InvoiceBuilderTest.php @@ -48,8 +48,8 @@ private function createInvoice(string $gateway, array $data): Invoice if (isset($data['expiresAt'])) { $invoiceBuilder->setExpiresAt($data['expiresAt']); } - if (isset($data['paymentMethod'])) { - $invoiceBuilder->setPaymentMethod($data['paymentMethod']); + if (isset($data['availablePaymentMethods'])) { + $invoiceBuilder->setAvailablePaymentMethods($data['availablePaymentMethods']); } if (isset($data['creditCard'])) { $invoiceBuilder->addCreditCard( @@ -137,7 +137,7 @@ public function testShouldCreateInvoice(string $gateway, array $data): void $this->assertNotEmpty($invoice->creditCard->id); } - if ((isset($data['paymentMethod']) && $data['paymentMethod'] === 'bank_slip') || (isset($data['gatewayAdicionalOptions']) && in_array('payable_with', $data['gatewayAdicionalOptions']) && in_array('bank_slip', $data['gatewayAdicionalOptions']['payable_with']))) { + if ((isset($data['availablePaymentMethods']) && in_array('bank_slip', $data['availablePaymentMethods'])) || (isset($data['paymentMethod']) && $data['paymentMethod'] === 'bank_slip') || (isset($data['gatewayAdicionalOptions']) && in_array('payable_with', $data['gatewayAdicionalOptions']) && in_array('bank_slip', $data['gatewayAdicionalOptions']['payable_with']))) { $this->assertNotEmpty($invoice->bankSlip); $this->assertNotEmpty($invoice->bankSlip->url); $this->assertNotEmpty($invoice->bankSlip->number); @@ -145,7 +145,8 @@ public function testShouldCreateInvoice(string $gateway, array $data): void $this->assertNotEmpty($invoice->bankSlip->barcodeImage); } - if ((isset($data['paymentMethod']) && $data['paymentMethod'] === 'pix') || (isset($data['gatewayAdicionalOptions']) && in_array('payable_with', $data['gatewayAdicionalOptions']) && in_array('pix', $data['gatewayAdicionalOptions']['payable_with']))) { + if ((isset($data['availablePaymentMethods']) && in_array('pix', $data['availablePaymentMethods'])) || (isset($data['paymentMethod']) && $data['paymentMethod'] === 'pix') || (isset($data['gatewayAdicionalOptions']) && in_array('payable_with', $data['gatewayAdicionalOptions']) && in_array('pix', $data['gatewayAdicionalOptions']['payable_with']))) { + $this->assertNotEmpty($invoice->pix); $this->assertNotEmpty($invoice->pix->qrCodeImageUrl); $this->assertNotEmpty($invoice->pix->qrCodeText); @@ -258,7 +259,7 @@ public function shouldCreateInvoiceDataProvider(): array 'data' => [ 'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]], 'customer' => self::customerWithoutAddress(), - 'paymentMethod' => 'credit_card', + 'availablePaymentMethods' => ['credit_card'], 'creditCard' => self::creditCard(), ] ], @@ -267,7 +268,7 @@ public function shouldCreateInvoiceDataProvider(): array 'data' => [ 'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]], 'customer' => self::customerWithAddress(), - 'paymentMethod' => 'credit_card', + 'availablePaymentMethods' => ['credit_card'], 'creditCard' => self::creditCard(), ] ], @@ -277,7 +278,7 @@ public function shouldCreateInvoiceDataProvider(): array 'expiresAt' => Carbon::now()->addWeekday()->format('Y-m-d'), 'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]], 'customer' => self::customerWithAddress(), - 'paymentMethod' => 'bank_slip', + 'availablePaymentMethods' => ['bank_slip'], ] ], 'iugu - pix with address' => [ @@ -286,7 +287,7 @@ public function shouldCreateInvoiceDataProvider(): array 'expiresAt' => Carbon::now()->addWeekday()->format('Y-m-d'), 'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]], 'customer' => self::customerWithAddress(), - 'paymentMethod' => 'pix', + 'availablePaymentMethods' => ['pix'], ] ], 'iugu - pix without address' => [ @@ -295,7 +296,7 @@ public function shouldCreateInvoiceDataProvider(): array 'expiresAt' => Carbon::now()->addWeekday()->format('Y-m-d'), 'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]], 'customer' => self::customerWithoutAddress(), - 'paymentMethod' => 'pix', + 'availablePaymentMethods' => ['pix'], ] ], ]; @@ -325,7 +326,7 @@ public function shouldNotCreateInvoiceDataProvider(): array 'data' => [ 'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]], 'customer' => self::customerWithAddress(), - 'paymentMethod' => 'credit_card', + 'availablePaymentMethods' => ['credit_card'], 'creditCard' => array_merge(self::creditCard(), ['number' => '4012888888881881']), ], ], diff --git a/tests/Unit/MultiPaymentTest.php b/tests/Unit/MultiPaymentTest.php index acd5963..22e0fcd 100644 --- a/tests/Unit/MultiPaymentTest.php +++ b/tests/Unit/MultiPaymentTest.php @@ -20,7 +20,7 @@ public function testShouldGetInvoice() { $gateway = 'iugu'; $invoice = MultiPayment::setGateway($gateway)->newInvoice() - ->setPaymentMethod(Invoice::PAYMENT_METHOD_CREDIT_CARD) + ->addAvailablePaymentMethod(Invoice::PAYMENT_METHOD_CREDIT_CARD) ->addCustomer('Fake Customer', 'email@exemplo.com', '20176996915') ->addItem('teste', 1000, 1) ->addCreditCardToken(self::iuguCreditCardToken()) @@ -90,7 +90,7 @@ public function testShouldRefundInvoice(string $gateway, array $data, string $st $invoiceBuilder->addItem($item['description'], $item['price'], $item['quantity']); $total += $item['price'] * $item['quantity']; } - $invoiceBuilder->setPaymentMethod($data['paymentMethod']); + $invoiceBuilder->addAvailablePaymentMethod($data['paymentMethod']); $invoiceBuilder->addCreditCard( $data['creditCard']['number'] ?? null, $data['creditCard']['month'] ?? null,