Skip to content

Commit 6cb6c54

Browse files
ENGCOM-5527: GraphQl-644: [Checkout] Support of 'Braintree' payment method #392
- Merge Pull Request magento/graphql-ce#392 from pmclain/graphql-ce:feature/braintree-payment - Merged commits: 1. 93b08f6 2. 7f226f6 3. c7fd250 4. a59a919 5. 411a559 6. a784526 7. 5f25fdd 8. 4527ea2 9. d57d076 10. 05632a8 11. 3720ec0 12. a6e32e8 13. c4609cc 14. c1eee4f 15. 4939d9c 16. ba459a1 17. fe23996 18. 2448894 19. c552e35 20. e49df5b 21. 169ac1b 22. f69b080 23. ec719be 24. d757fb5 25. 1132a47 26. 6fc0322 27. 00002f4
2 parents 41daebf + 00002f4 commit 6cb6c54

File tree

21 files changed

+1475
-11
lines changed

21 files changed

+1475
-11
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\BraintreeGraphQl\Model;
9+
10+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
11+
use Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderInterface;
12+
13+
/**
14+
* Format Braintree input into value expected when setting payment method
15+
*/
16+
class BraintreeDataProvider implements AdditionalDataProviderInterface
17+
{
18+
private const PATH_ADDITIONAL_DATA = 'braintree';
19+
20+
/**
21+
* Format Braintree input into value expected when setting payment method
22+
*
23+
* @param array $args
24+
* @return array
25+
* @throws GraphQlInputException
26+
*/
27+
public function getData(array $args): array
28+
{
29+
if (!isset($args[self::PATH_ADDITIONAL_DATA])) {
30+
throw new GraphQlInputException(
31+
__('Required parameter "braintree" for "payment_method" is missing.')
32+
);
33+
}
34+
35+
if (!isset($args[self::PATH_ADDITIONAL_DATA]['payment_method_nonce'])) {
36+
throw new GraphQlInputException(
37+
__('Required parameter "payment_method_nonce" for "braintree" is missing.')
38+
);
39+
}
40+
41+
if (!isset($args[self::PATH_ADDITIONAL_DATA]['is_active_payment_token_enabler'])) {
42+
throw new GraphQlInputException(
43+
__('Required parameter "is_active_payment_token_enabler" for "braintree" is missing.')
44+
);
45+
}
46+
47+
return $args[self::PATH_ADDITIONAL_DATA];
48+
}
49+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\BraintreeGraphQl\Model;
9+
10+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
11+
use Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderInterface;
12+
13+
/**
14+
* Format Braintree input into value expected when setting payment method
15+
*/
16+
class BraintreeVaultDataProvider implements AdditionalDataProviderInterface
17+
{
18+
private const PATH_ADDITIONAL_DATA = 'braintree_cc_vault';
19+
20+
/**
21+
* Format Braintree input into value expected when setting payment method
22+
*
23+
* @param array $args
24+
* @return array
25+
*/
26+
public function getData(array $args): array
27+
{
28+
if (!isset($args[self::PATH_ADDITIONAL_DATA])) {
29+
throw new GraphQlInputException(
30+
__('Required parameter "braintree_cc_vault" for "payment_method" is missing.')
31+
);
32+
}
33+
34+
if (!isset($args[self::PATH_ADDITIONAL_DATA]['public_hash'])) {
35+
throw new GraphQlInputException(
36+
__('Required parameter "public_hash" for "braintree_cc_vault" is missing.')
37+
);
38+
}
39+
40+
return $args[self::PATH_ADDITIONAL_DATA];
41+
}
42+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\BraintreeGraphQl\Model\Resolver;
9+
10+
use Magento\Braintree\Gateway\Config\Config;
11+
use Magento\Braintree\Gateway\Request\PaymentDataBuilder;
12+
use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
15+
use Magento\Framework\GraphQl\Query\ResolverInterface;
16+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
17+
use Magento\Store\Model\StoreManagerInterface;
18+
19+
/**
20+
* Resolver for generating Braintree client token
21+
*/
22+
class CreateBraintreeClientToken implements ResolverInterface
23+
{
24+
/**
25+
* @var Config
26+
*/
27+
private $config;
28+
29+
/**
30+
* @var BraintreeAdapterFactory
31+
*/
32+
private $adapterFactory;
33+
34+
/**
35+
* @param Config $config
36+
* @param BraintreeAdapterFactory $adapterFactory
37+
*/
38+
public function __construct(
39+
Config $config,
40+
BraintreeAdapterFactory $adapterFactory
41+
) {
42+
$this->config = $config;
43+
$this->adapterFactory = $adapterFactory;
44+
}
45+
46+
/**
47+
* @inheritdoc
48+
*/
49+
public function resolve(
50+
Field $field,
51+
$context,
52+
ResolveInfo $info,
53+
array $value = null,
54+
array $args = null
55+
) {
56+
$storeId = (int)$context->getExtensionAttributes()->getStore()->getId();
57+
58+
if (!$this->config->isActive($storeId)) {
59+
throw new GraphQlInputException(__('The Braintree payment method is not active.'));
60+
}
61+
62+
$params = [];
63+
$merchantAccountId = $this->config->getMerchantAccountId($storeId);
64+
if (!empty($merchantAccountId)) {
65+
$params[PaymentDataBuilder::MERCHANT_ACCOUNT_ID] = $merchantAccountId;
66+
}
67+
68+
return $this->adapterFactory->create($storeId)->generate($params);
69+
}
70+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\BraintreeGraphQl\Plugin;
9+
10+
use Magento\Braintree\Gateway\Command\GetPaymentNonceCommand;
11+
use Magento\Braintree\Model\Ui\ConfigProvider;
12+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
13+
use Psr\Log\LoggerInterface;
14+
15+
/**
16+
* Plugin creating nonce from Magento Vault Braintree public hash
17+
*/
18+
class SetVaultPaymentNonce
19+
{
20+
/**
21+
* @var GetPaymentNonceCommand
22+
*/
23+
private $command;
24+
25+
/**
26+
* @var LoggerInterface
27+
*/
28+
private $logger;
29+
30+
/**
31+
* @param GetPaymentNonceCommand $command
32+
* @param LoggerInterface $logger
33+
*/
34+
public function __construct(
35+
GetPaymentNonceCommand $command,
36+
LoggerInterface $logger
37+
) {
38+
$this->command = $command;
39+
$this->logger = $logger;
40+
}
41+
42+
/**
43+
* Set Braintree nonce from public hash
44+
*
45+
* @param \Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart $subject
46+
* @param \Magento\Quote\Model\Quote $quote
47+
* @param array $paymentData
48+
* @return array
49+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
50+
*/
51+
public function beforeExecute(
52+
\Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart $subject,
53+
\Magento\Quote\Model\Quote $quote,
54+
array $paymentData
55+
): array {
56+
if ($paymentData['code'] !== ConfigProvider::CC_VAULT_CODE
57+
|| !isset($paymentData[ConfigProvider::CC_VAULT_CODE])
58+
|| !isset($paymentData[ConfigProvider::CC_VAULT_CODE]['public_hash'])
59+
) {
60+
return [$quote, $paymentData];
61+
}
62+
63+
$subject = [
64+
'public_hash' => $paymentData[ConfigProvider::CC_VAULT_CODE]['public_hash'],
65+
'customer_id' => $quote->getCustomerId(),
66+
'store_id' => $quote->getStoreId(),
67+
];
68+
69+
try {
70+
$result = $this->command->execute($subject)->get();
71+
$paymentData[ConfigProvider::CC_VAULT_CODE]['payment_method_nonce'] = $result['paymentMethodNonce'];
72+
} catch (\Exception $e) {
73+
$this->logger->critical($e);
74+
throw new GraphQlInputException(__('Sorry, but something went wrong'));
75+
}
76+
77+
return [$quote, $paymentData];
78+
}
79+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# BraintreeGraphQl
2+
3+
**BraintreeGraphQl** provides type and resolver for method additional
4+
information.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "magento/module-braintree-graph-ql",
3+
"description": "N/A",
4+
"type": "magento2-module",
5+
"require": {
6+
"php": "~7.1.3||~7.2.0||~7.3.0",
7+
"magento/framework": "*",
8+
"magento/module-braintree": "*",
9+
"magento/module-store": "*",
10+
"magento/module-quote": "*",
11+
"magento/module-quote-graph-ql": "*"
12+
},
13+
"suggest": {
14+
"magento/module-graph-ql": "*"
15+
},
16+
"license": [
17+
"OSL-3.0",
18+
"AFL-3.0"
19+
],
20+
"autoload": {
21+
"files": [
22+
"registration.php"
23+
],
24+
"psr-4": {
25+
"Magento\\BraintreeGraphQl\\": ""
26+
}
27+
}
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<type name="Magento\QuoteGraphQl\Model\Cart\Payment\AdditionalDataProviderPool">
10+
<arguments>
11+
<argument name="dataProviders" xsi:type="array">
12+
<item name="braintree" xsi:type="object">Magento\BraintreeGraphQl\Model\BraintreeDataProvider</item>
13+
<item name="braintree_cc_vault" xsi:type="object">Magento\BraintreeGraphQl\Model\BraintreeVaultDataProvider</item>
14+
</argument>
15+
</arguments>
16+
</type>
17+
<type name="Magento\QuoteGraphQl\Model\Cart\SetPaymentMethodOnCart">
18+
<plugin name="braintree_generate_vault_nonce" type="Magento\BraintreeGraphQl\Plugin\SetVaultPaymentNonce" />
19+
</type>
20+
</config>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
9+
<module name="Magento_BraintreeGraphQl">
10+
<sequence>
11+
<module name="Magento_Braintree"/>
12+
<module name="Magento_Quote"/>
13+
<module name="Magento_Store"/>
14+
<module name="Magento_QuoteGraphQl"/>
15+
</sequence>
16+
</module>
17+
</config>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
type Mutation {
5+
createBraintreeClientToken: String! @resolver(class: "\\Magento\\BraintreeGraphQl\\Model\\Resolver\\CreateBraintreeClientToken") @doc(description:"Creates Braintree Client Token for creating client-side nonce.")
6+
}
7+
8+
input PaymentMethodInput {
9+
braintree: BraintreeInput
10+
braintree_cc_vault: BraintreeCcVaultInput
11+
}
12+
13+
input BraintreeInput {
14+
payment_method_nonce: String!
15+
is_active_payment_token_enabler: Boolean!
16+
device_data: String
17+
}
18+
19+
input BraintreeCcVaultInput {
20+
public_hash: String!
21+
device_data: String
22+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Framework\Component\ComponentRegistrar;
9+
10+
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_BraintreeGraphQl', __DIR__);

0 commit comments

Comments
 (0)