Skip to content

Commit

Permalink
Merge pull request #5 from TepuiLABS/feature-stripe
Browse files Browse the repository at this point in the history
Agrega base funcional de stripe
  • Loading branch information
abr4xas authored Feb 25, 2021
2 parents 16ecdd0 + d792d8e commit 098a63e
Show file tree
Hide file tree
Showing 4 changed files with 278 additions and 0 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ return [
'class' => \Tepuilabs\PaymentProcessors\Services\PayPalService::class,
],

'stripe' => [
'class' => \Tepuilabs\PaymentProcessors\Services\StripeService::class,
],

];
```

Expand Down Expand Up @@ -144,6 +148,43 @@ $paypal->handleApproval();

</details>

<details>
<summary>Stripe</summary>
Para usar Stripe solamente debemos usar dos metodos:

```php
// usa el facade
use Tepuilabs\PaymentProcessors\Facades\PaymentProcessors;

// luego crea la instancia de la clase a usar

$params = [
'key' => 'pk_test_51IMzM0...',
'secret' => 'sk_test_51IM...',
];

$stripe = PaymentProcessors::resolveService('stripe', $params);

// Para generar el payment method id te recomiendo leer esto: https://github.com/TepuiLABS/payment-processors/discussions/6
// Para saber que es el payment method te invito a leer la documentación: https://stripe.com/docs/api/payment_methods

// Despues de obtener el payment method id pasamos a generar el pago de la siguiente forma:

$paymentData = [
'amount' => 501.52,
'paymentMethod' => $paymentMethodId, // pm_1IOYCAJcoyM5FfOy0cVbjyuH
];

$intent = $stripe->handlePayment($paymentData);

// Y ya por ultimo, confirmamos el pago:

$confirm = $stripe->confirmPayment($intent['id']);

```

</details>

## Testing

```bash
Expand Down
4 changes: 4 additions & 0 deletions config/payment-processors.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@
'class' => \Tepuilabs\PaymentProcessors\Services\PayPalService::class,
],

'stripe' => [
'class' => \Tepuilabs\PaymentProcessors\Services\StripeService::class,
],

];
131 changes: 131 additions & 0 deletions src/Services/StripeService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

namespace Tepuilabs\PaymentProcessors\Services;

use Tepuilabs\PaymentProcessors\Traits\ConsumeExternalServices;

class StripeService
{
use ConsumeExternalServices;

protected string $baseUri;
protected string $key;
protected string $secret;

private array $apiKeys;

final public function __construct(array $apiKeys)
{
$this->baseUri = 'https://api.stripe.com';
$this->key = $apiKeys['key'];
$this->secret = $apiKeys['secret'];
}

public static function paymentService(array $apiKeys): self
{
return new static($apiKeys);
}

public function resolveAuthorization(array &$queryParams, array &$formParams, array &$headers): void
{
$headers['Authorization'] = $this->resolveAccessToken();
}

public function decodeResponse(string $response): array
{
return (array) json_decode($response, true);
}

/**
* resolveAccessToken
*
* @return string
*/
public function resolveAccessToken(): string
{
return "Bearer {$this->secret}";
}

/**
* Undocumented function
*
* @param array $paymentData
* @return \Psr\Http\Message\StreamInterface|array
* @psalm-suppress UndefinedInterfaceMethod
*/
public function handlePayment(array $paymentData)
{
$currency = isset($paymentData['currency']) ? $paymentData['currency'] : 'USD';
$amount = $paymentData['amount'];
$paymentMethod = $paymentData['paymentMethod'];

return $this->createIntent($amount, $currency, $paymentMethod);
}

/**
* Undocumented function
*
* @return \Psr\Http\Message\StreamInterface|array
*/
public function handleApproval()
{
return [];
}

/**
* Undocumented function
*
* @param float $value
* @param string $currency
* @param string $paymentMethod
* @return \Psr\Http\Message\StreamInterface|array
*/
public function createIntent(float $value, string $currency, string $paymentMethod)
{
return $this->makeRequest(
'POST',
'/v1/payment_intents',
[],
[
'amount' => round($value * $this->resolveFactor($currency)),
'currency' => strtolower($currency),
'payment_method' => $paymentMethod,
'confirmation_method' => 'manual',
'payment_method_types' => [
'card',
],
],
);
}

/**
* Undocumented function
*
* @param string $paymentIntentId
* @return \Psr\Http\Message\StreamInterface|array
*/
public function confirmPayment(string $paymentIntentId)
{
return $this->makeRequest(
'POST',
"/v1/payment_intents/{$paymentIntentId}/confirm",
);
}

/**
* Undocumented function
*
* @param string $currency
* @return int
*/
private function resolveFactor(string $currency)
{
$zeroDecimalCurrencies = ['JPY'];

if (in_array(strtoupper($currency), $zeroDecimalCurrencies)) {
return 1;
}

return 100;
}
}
102 changes: 102 additions & 0 deletions tests/Feature/StripeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

namespace Tepuilabs\PaymentProcessors\Tests\Feature;

use Tepuilabs\PaymentProcessors\Facades\PaymentProcessors;
use Tepuilabs\PaymentProcessors\Tests\TestCase;

class StripeTest extends TestCase
{
/** @test */
public function test_it_can_resolve_class()
{
$params = [
'key' => 'pk_test_51IMzM0JcoyM5FfOypXlbYcOcg9EsrAwfhLikFrK436CqIGIRxysFz1G45NtJJik4NCVAje8xUddeeD0KjVeNe5Rf00JyWoyvEi',
'secret' => 'sk_test_51IMzM0JcoyM5FfOyoV47UeCAMpHFvkrPOrVRM0B83tE6NEffMlLJCuX09jh6Gv6nXKwx5pR3nWaBp5z4TPP08zIY00z3CLwJJw',
];

$stripe = PaymentProcessors::resolveService('stripe', $params);

$this->assertInstanceOf(\Tepuilabs\PaymentProcessors\Services\StripeService::class, $stripe);
}

/** @test */
public function test_it_can_get_balance()
{
$params = [
'key' => 'pk_test_51IMzM0JcoyM5FfOypXlbYcOcg9EsrAwfhLikFrK436CqIGIRxysFz1G45NtJJik4NCVAje8xUddeeD0KjVeNe5Rf00JyWoyvEi',
'secret' => 'sk_test_51IMzM0JcoyM5FfOyoV47UeCAMpHFvkrPOrVRM0B83tE6NEffMlLJCuX09jh6Gv6nXKwx5pR3nWaBp5z4TPP08zIY00z3CLwJJw',
];

$stripe = PaymentProcessors::resolveService('stripe', $params);

$balance = $stripe->makeRequest('GET', '/v1/balance');

$this->assertIsArray($balance, 'assert variable is array or not');
}

/** @test */
public function test_it_can_generate_a_payment_method_id()
{
$params = [
'key' => 'pk_test_51IMzM0JcoyM5FfOypXlbYcOcg9EsrAwfhLikFrK436CqIGIRxysFz1G45NtJJik4NCVAje8xUddeeD0KjVeNe5Rf00JyWoyvEi',
'secret' => 'sk_test_51IMzM0JcoyM5FfOyoV47UeCAMpHFvkrPOrVRM0B83tE6NEffMlLJCuX09jh6Gv6nXKwx5pR3nWaBp5z4TPP08zIY00z3CLwJJw',
];

$stripe = PaymentProcessors::resolveService('stripe', $params);

// only for test
$paymentMethod = $stripe->makeRequest('POST', '/v1/payment_methods', [], [
'type' => 'card',
'card' => [
'number' => '4242424242424242',
'exp_month' => 2,
'exp_year' => 2022,
'cvc' => '314',
],
]);

$paymentMethodId = $paymentMethod['id'];

$this->assertIsString($paymentMethodId);

return $paymentMethodId;
}

/** @depends test_it_can_generate_a_payment_method_id */
public function test_it_can_handle_a_payment($paymentMethodId)
{
$params = [
'key' => 'pk_test_51IMzM0JcoyM5FfOypXlbYcOcg9EsrAwfhLikFrK436CqIGIRxysFz1G45NtJJik4NCVAje8xUddeeD0KjVeNe5Rf00JyWoyvEi',
'secret' => 'sk_test_51IMzM0JcoyM5FfOyoV47UeCAMpHFvkrPOrVRM0B83tE6NEffMlLJCuX09jh6Gv6nXKwx5pR3nWaBp5z4TPP08zIY00z3CLwJJw',
];

$stripe = PaymentProcessors::resolveService('stripe', $params);

$paymentData = [
'amount' => 501.52,
'paymentMethod' => $paymentMethodId,
];

$intent = $stripe->handlePayment($paymentData);

$this->assertIsArray($intent, 'assert variable is array or not');

return $intent;
}

/** @depends test_it_can_handle_a_payment */
public function test_it_can_confirm_a_payment($intent)
{
$params = [
'key' => 'pk_test_51IMzM0JcoyM5FfOypXlbYcOcg9EsrAwfhLikFrK436CqIGIRxysFz1G45NtJJik4NCVAje8xUddeeD0KjVeNe5Rf00JyWoyvEi',
'secret' => 'sk_test_51IMzM0JcoyM5FfOyoV47UeCAMpHFvkrPOrVRM0B83tE6NEffMlLJCuX09jh6Gv6nXKwx5pR3nWaBp5z4TPP08zIY00z3CLwJJw',
];

$stripe = PaymentProcessors::resolveService('stripe', $params);

$confirm = $stripe->confirmPayment($intent['id']);

$this->assertEquals('succeeded', $confirm['status'], 'actual value is not equals to expected');
}
}

0 comments on commit 098a63e

Please sign in to comment.