Skip to content
This repository was archived by the owner on Dec 19, 2019. It is now read-only.

Commit a0889d3

Browse files
committed
Add endpoint for fetching/deleting vault tokens
1 parent d88cf06 commit a0889d3

File tree

12 files changed

+538
-2
lines changed

12 files changed

+538
-2
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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\VaultGraphQl\Model;
9+
10+
use Magento\Framework\Api\FilterBuilder;
11+
use Magento\Framework\Api\SearchCriteriaBuilder;
12+
use Magento\Framework\Intl\DateTimeFactory;
13+
use Magento\Vault\Api\Data\PaymentTokenInterface;
14+
use Magento\Vault\Api\Data\PaymentTokenSearchResultsInterfaceFactory;
15+
use Magento\Vault\Api\PaymentTokenRepositoryInterface;
16+
17+
/**
18+
* Vault payment token repository
19+
*/
20+
class PaymentTokenManagement
21+
{
22+
/**
23+
* @var PaymentTokenRepositoryInterface
24+
*/
25+
protected $paymentTokenRepository;
26+
27+
/**
28+
* @var PaymentTokenSearchResultsInterfaceFactory
29+
*/
30+
protected $searchResultsFactory;
31+
32+
/**
33+
* @var \Magento\Framework\Api\FilterBuilder
34+
*/
35+
protected $filterBuilder;
36+
37+
/**
38+
* @var \Magento\Framework\Api\SearchCriteriaBuilder
39+
*/
40+
protected $searchCriteriaBuilder;
41+
42+
/**
43+
* @var DateTimeFactory
44+
*/
45+
private $dateTimeFactory;
46+
47+
/**
48+
* @param PaymentTokenRepositoryInterface $repository
49+
* @param FilterBuilder $filterBuilder
50+
* @param SearchCriteriaBuilder $searchCriteriaBuilder
51+
* @param PaymentTokenSearchResultsInterfaceFactory $searchResultsFactory
52+
* @param DateTimeFactory $dateTimeFactory
53+
*/
54+
public function __construct(
55+
PaymentTokenRepositoryInterface $repository,
56+
FilterBuilder $filterBuilder,
57+
SearchCriteriaBuilder $searchCriteriaBuilder,
58+
PaymentTokenSearchResultsInterfaceFactory $searchResultsFactory,
59+
DateTimeFactory $dateTimeFactory
60+
) {
61+
$this->paymentTokenRepository = $repository;
62+
$this->filterBuilder = $filterBuilder;
63+
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
64+
$this->searchResultsFactory = $searchResultsFactory;
65+
$this->dateTimeFactory = $dateTimeFactory;
66+
}
67+
68+
/**
69+
* Searches for all visible, non-expired tokens
70+
*
71+
* @param int $customerId
72+
* @return PaymentTokenInterface[]
73+
*/
74+
public function getVisibleAvailableTokens($customerId)
75+
{
76+
$customerFilter = [
77+
$this->filterBuilder->setField(PaymentTokenInterface::CUSTOMER_ID)
78+
->setValue($customerId)
79+
->create()
80+
];
81+
$visibleFilter = [
82+
$this->filterBuilder->setField(PaymentTokenInterface::IS_VISIBLE)
83+
->setValue(1)
84+
->create()
85+
];
86+
$isActiveFilter = [
87+
$this->filterBuilder->setField(PaymentTokenInterface::IS_ACTIVE)
88+
->setValue(1)
89+
->create()
90+
];
91+
$expiresAtFilter = [
92+
$this->filterBuilder->setField(PaymentTokenInterface::EXPIRES_AT)
93+
->setConditionType('gt')
94+
->setValue(
95+
$this->dateTimeFactory->create(
96+
'now',
97+
new \DateTimeZone('UTC')
98+
)->format('Y-m-d 00:00:00')
99+
)
100+
->create()
101+
];
102+
$this->searchCriteriaBuilder->addFilters($customerFilter);
103+
$this->searchCriteriaBuilder->addFilters($visibleFilter);
104+
$this->searchCriteriaBuilder->addFilters($isActiveFilter);
105+
// add filters to different filter groups in order to filter by AND expression
106+
$searchCriteria = $this->searchCriteriaBuilder->addFilters($expiresAtFilter)->create();
107+
108+
return $this->paymentTokenRepository->getList($searchCriteria)->getItems();
109+
}
110+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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\VaultGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Config\Element\Field;
11+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
12+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
13+
use Magento\Framework\GraphQl\Query\ResolverInterface;
14+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
15+
use Magento\Vault\Api\PaymentTokenManagementInterface;
16+
use Magento\Vault\Api\PaymentTokenRepositoryInterface;
17+
use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount;
18+
19+
/**
20+
* Payment Token resolver, used for GraphQL request processing.
21+
*/
22+
class DeletePaymentToken implements ResolverInterface
23+
{
24+
/**
25+
* @var CheckCustomerAccount
26+
*/
27+
private $checkCustomerAccount;
28+
29+
/**
30+
* @var PaymentTokenManagementInterface
31+
*/
32+
private $paymentTokenManagement;
33+
34+
/**
35+
* @var PaymentTokenRepositoryInterface
36+
*/
37+
private $paymentTokenRepository;
38+
39+
/**
40+
* @param CheckCustomerAccount $checkCustomerAccount
41+
* @param PaymentTokenManagementInterface $paymentTokenManagement
42+
* @param PaymentTokenRepositoryInterface $paymentTokenRepository
43+
*/
44+
public function __construct(
45+
CheckCustomerAccount $checkCustomerAccount,
46+
PaymentTokenManagementInterface $paymentTokenManagement,
47+
PaymentTokenRepositoryInterface $paymentTokenRepository
48+
) {
49+
$this->checkCustomerAccount = $checkCustomerAccount;
50+
$this->paymentTokenManagement = $paymentTokenManagement;
51+
$this->paymentTokenRepository = $paymentTokenRepository;
52+
}
53+
54+
/**
55+
* @inheritdoc
56+
*/
57+
public function resolve(
58+
Field $field,
59+
$context,
60+
ResolveInfo $info,
61+
array $value = null,
62+
array $args = null
63+
) {
64+
if (!isset($args['public_hash'])) {
65+
throw new GraphQlInputException(__('Specify the "public_hash" value.'));
66+
}
67+
68+
$currentUserId = $context->getUserId();
69+
$currentUserType = $context->getUserType();
70+
71+
$this->checkCustomerAccount->execute($currentUserId, $currentUserType);
72+
73+
$token = $this->paymentTokenManagement->getByPublicHash($args['public_hash'], $currentUserId);
74+
if (!$token) {
75+
throw new GraphQlNoSuchEntityException(__('Token could not be found by public hash: %1', $args['public_hash']));
76+
}
77+
78+
return ['result' => $this->paymentTokenRepository->delete($token)];
79+
}
80+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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\VaultGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Config\Element\Field;
11+
use Magento\Framework\GraphQl\Query\ResolverInterface;
12+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13+
use Magento\VaultGraphQl\Model\PaymentTokenManagement;
14+
use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount;
15+
16+
/**
17+
* Customers Payment Tokens resolver, used for GraphQL request processing.
18+
*/
19+
class PaymentTokens implements ResolverInterface
20+
{
21+
/**
22+
* @var PaymentTokenManagement
23+
*/
24+
private $paymentTokenManagement;
25+
26+
/**
27+
* @var CheckCustomerAccount
28+
*/
29+
private $checkCustomerAccount;
30+
31+
/**
32+
* @param PaymentTokenManagement $paymentTokenManagement
33+
* @param CheckCustomerAccount $checkCustomerAccount
34+
*/
35+
public function __construct(
36+
PaymentTokenManagement $paymentTokenManagement,
37+
CheckCustomerAccount $checkCustomerAccount
38+
) {
39+
$this->paymentTokenManagement = $paymentTokenManagement;
40+
$this->checkCustomerAccount = $checkCustomerAccount;
41+
}
42+
43+
/**
44+
* @inheritdoc
45+
*/
46+
public function resolve(
47+
Field $field,
48+
$context,
49+
ResolveInfo $info,
50+
array $value = null,
51+
array $args = null
52+
) {
53+
$currentUserId = $context->getUserId();
54+
$currentUserType = $context->getUserType();
55+
56+
$this->checkCustomerAccount->execute($currentUserId, $currentUserType);
57+
58+
$tokens = $this->paymentTokenManagement->getVisibleAvailableTokens($currentUserId);
59+
$result = [];
60+
61+
foreach ($tokens as $token) {
62+
$result[] = [
63+
'public_hash' => $token->getPublicHash(),
64+
'payment_method_code' => $token->getPaymentMethodCode(),
65+
'type' => $token->getType(),
66+
'details' => $token->getTokenDetails(),
67+
];
68+
}
69+
70+
return ['items' => $result];
71+
}
72+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# VaultGraphQl
2+
3+
**VaultGraphQl** provides type and resolver information for the GraphQl module
4+
to generate Vault (stored payment information) information endpoints. Also
5+
provides endpoints for modifying a payment token.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "magento/module-vault-graph-ql",
3+
"description": "N/A",
4+
"type": "magento2-module",
5+
"require": {
6+
"php": "~7.1.3||~7.2.0",
7+
"magento/framework": "*",
8+
"magento/module-vault": "*",
9+
"magento/module-customer-graph-ql": "*"
10+
},
11+
"suggest": {
12+
"magento/module-graph-ql": "*"
13+
},
14+
"license": [
15+
"OSL-3.0",
16+
"AFL-3.0"
17+
],
18+
"autoload": {
19+
"files": [
20+
"registration.php"
21+
],
22+
"psr-4": {
23+
"Magento\\VaultGraphQl\\": ""
24+
}
25+
}
26+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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_VaultGraphQl" >
10+
<sequence>
11+
<module name="Magento_Vault"/>
12+
<module name="Magento_GraphQl"/>
13+
<module name="Magento_CustomerGraphQl"/>
14+
</sequence>
15+
</module>
16+
</config>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
type Mutation {
5+
deletePaymentToken(public_hash: String!): DeletePaymentTokenOutput @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\DeletePaymentToken") @doc(description:"Delete customer Payment Token")
6+
}
7+
8+
type DeletePaymentTokenOutput {
9+
result: Boolean!
10+
}
11+
12+
type Query {
13+
customerPaymentTokens: CustomerPaymentTokens @doc(description: "List of customer payment tokens") @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\PaymentTokens")
14+
}
15+
16+
type CustomerPaymentTokens {
17+
items: [PaymentToken] @doc(description: "An array of payment tokens")
18+
}
19+
20+
type PaymentToken @doc(description: "Stored payment method available to customer") {
21+
public_hash: String! @doc(description: "Token public hash")
22+
payment_method_code: String! @doc(description: "Payment method code associated with token")
23+
type: String! @doc(description: "Token type [card|account]")
24+
details: String @doc(description: "Stored account details")
25+
}
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_VaultGraphQl', __DIR__);

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@
234234
"magento/module-usps": "*",
235235
"magento/module-variable": "*",
236236
"magento/module-vault": "*",
237+
"magento/module-vault-graph-ql": "*",
237238
"magento/module-version": "*",
238239
"magento/module-webapi": "*",
239240
"magento/module-webapi-async": "*",

composer.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)