Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sending discounts #19

Merged
merged 3 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 48 additions & 13 deletions src/OrderBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class OrderBuilder
private string $externalId = '';
private string $currency = '';
private float $amount = 0;
private float $discount = 0;
private string $description = '';
private string $brandName = '';
private string $locale = 'es-AR';
Expand Down Expand Up @@ -48,6 +49,12 @@ public function amount(float $amount): OrderBuilder
return $this;
}

public function discount(float $discount): OrderBuilder
{
$this->discount = $discount;
return $this;
}

/**
* @param string $description
* @return OrderBuilder
Expand Down Expand Up @@ -100,32 +107,60 @@ public function cancelUrl(string $cancelUrl): OrderBuilder

public function make(): array
{
return [
$arr = [
'intent' => 'CAPTURE',
'purchase_units' => [
[
'custom_id' => $this->externalId,
'description' => $this->description,
'amount' => [
'currency_code' => $this->currency,
'value' => round($this->amount, 2),
'value' => round($this->amount - $this->discount, 2),
'breakdown' => [
'item_total' => [
'currency_code' => $this->currency,
'value' => round($this->amount, 2),
],
],
],
'items' => [
[
'name' => $this->description,
'quantity' => '1',
'custom_id' => $this->externalId,
'unit_amount' => [
'currency_code' => $this->currency,
'value' => round($this->amount, 2),
],
'category' => 'DIGITAL_GOODS'
]
],
'description' => $this->description,
'payment_options' => [
'allowed_payment_method' => 'INSTANT_FUNDING_SOURCE'
],
]
],
'application_context' => [
'brand_name' => $this->brandName,
'locale' => $this->locale,
'user_action' => 'PAY_NOW',
'payment_method' => [
'payee_preferred' => 'IMMEDIATE_PAYMENT_REQUIRED',
],
'shipping_preference' => 'NO_SHIPPING',
'return_url' => $this->returnUrl,
'cancel_url' => $this->cancelUrl
'payment_source' => [
'paypal' => [
'experience_context' => [
'brand_name' => $this->brandName,
'shipping_preference' => 'NO_SHIPPING',
'user_action' => 'PAY_NOW',
'payment_method_preference' => 'IMMEDIATE_PAYMENT_REQUIRED',
'locale' => $this->locale,
'return_url' => $this->returnUrl,
'cancel_url' => $this->cancelUrl
]
]
],
];

if ($this->discount > 0) {
$arr['purchase_units'][0]['amount']['breakdown']['discount'] = [
'currency_code' => $this->currency,
'value' => round($this->discount, 2),
];
}
return $arr;
}
}
105 changes: 96 additions & 9 deletions tests/OrderBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,110 @@ public function create_order_with_int_amount()
'amount' => [
'currency_code' => 'USD',
'value' => 23.21,
'breakdown' => [
'item_total' => [
'currency_code' => 'USD',
'value' => 23.21,
],
]
],
'description' => 'My custom product',
'payment_options' => [
'allowed_payment_method' => 'INSTANT_FUNDING_SOURCE'
],
'items' => [
[
'name' => 'My custom product',
'quantity' => '1',
'custom_id' => '31fe5538-8589-437d-8823-3b0574186a5f',
'unit_amount' => [
'currency_code' => 'USD',
'value' => 23.21,
],
'category' => 'DIGITAL_GOODS',
]
]
]
],
'application_context' => [
'brand_name' => 'My brand name',
'locale' => 'es-AR',
'user_action' => 'PAY_NOW',
'payment_method' => [
'payee_preferred' => 'IMMEDIATE_PAYMENT_REQUIRED',
'payment_source' => [
'paypal' => [
'experience_context' => [
'brand_name' => 'My brand name',
'locale' => 'es-AR',
'user_action' => 'PAY_NOW',
'payment_method_preference' => 'IMMEDIATE_PAYMENT_REQUIRED',
'shipping_preference' => 'NO_SHIPPING',
'return_url' => 'http://localhost:8080/return',
'cancel_url' => 'http://localhost:8080/cancel'
],
],
],
], $order);
}

#[Test]
public function create_order_with_discount()
{
$order = (new OrderBuilder())
->externalId('31fe5538-8589-437d-8823-3b0574186a5f')
->currency('USD')
->amount(23.99)
->discount(3.98)
->description('My custom product')
->brandName('My brand name')
->returnUrl('http://localhost:8080/return')
->cancelUrl('http://localhost:8080/cancel')
->make();

$this->assertEquals([
'intent' => 'CAPTURE',
'purchase_units' => [
[
'custom_id' => '31fe5538-8589-437d-8823-3b0574186a5f',
'amount' => [
'currency_code' => 'USD',
'value' => 20.01,
'breakdown' => [
'item_total' => [
'currency_code' => 'USD',
'value' => 23.99,
],
'discount' => [
'currency_code' => 'USD',
'value' => 3.98,
],
]
],
'description' => 'My custom product',
'payment_options' => [
'allowed_payment_method' => 'INSTANT_FUNDING_SOURCE'
],
'items' => [
[
'name' => 'My custom product',
'quantity' => '1',
'custom_id' => '31fe5538-8589-437d-8823-3b0574186a5f',
'unit_amount' => [
'currency_code' => 'USD',
'value' => 23.99,
],
'category' => 'DIGITAL_GOODS',
]
]
]
],
'payment_source' => [
'paypal' => [
'experience_context' => [
'brand_name' => 'My brand name',
'locale' => 'es-AR',
'user_action' => 'PAY_NOW',
'payment_method_preference' => 'IMMEDIATE_PAYMENT_REQUIRED',
'shipping_preference' => 'NO_SHIPPING',
'return_url' => 'http://localhost:8080/return',
'cancel_url' => 'http://localhost:8080/cancel'
],
],
'shipping_preference' => 'NO_SHIPPING',
'return_url' => 'http://localhost:8080/return',
'cancel_url' => 'http://localhost:8080/cancel'
],
], $order);
}
Expand Down
17 changes: 4 additions & 13 deletions tests/PayPalApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Exception;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Log;
use PHPUnit\Framework\Attributes\Test;
use Puntodev\Payments\OrderBuilder;
use Puntodev\Payments\PayPalApi;
Expand All @@ -26,13 +25,6 @@ public function setUp(): void
);
}

protected function getEnvironmentSetUp($app)
{
$app['config']->set('paypal.client_id', env('PAYPAL_API_CLIENT_ID'));
$app['config']->set('paypal.client_secret', env('PAYPAL_API_CLIENT_SECRET'));
$app['config']->set('paypal.use_sandbox', env('SANDBOX_GATEWAYS'));
}

#[Test]
public function verify_ipn()
{
Expand All @@ -50,26 +42,25 @@ public function create_order()
->externalId($this->faker->uuid)
->currency('USD')
->amount(23.20)
->discount(2.19999)
->description('My custom product')
->brandName('My brand name')
->returnUrl('http://localhost:8080/return')
->cancelUrl('http://localhost:8080/cancel')
->make();

$createdOrder = $this->paypalApi->createOrder($order);
Log::debug('Created Order: ', ['createdOrder' => $createdOrder]);

$this->assertEquals('CREATED', $createdOrder['status']);
$this->assertCount(4, $createdOrder['links']);
$this->assertEquals('PAYER_ACTION_REQUIRED', $createdOrder['status']);
$this->assertCount(2, $createdOrder['links']);
$link = collect($createdOrder['links'])
->filter(function ($link) {
return $link['method'] === 'GET' && $link['rel'] === 'approve';
return $link['method'] === 'GET' && $link['rel'] === 'payer-action';
})
->first();
$this->assertStringStartsWith('https://www.sandbox.paypal.com/checkoutnow', $link['href']);
}


/**
* @return void
* @throws Exception
Expand Down