Skip to content

Commit 2c46b1e

Browse files
authored
Payment code recipes page (#304)
1 parent 8e48d1c commit 2c46b1e

File tree

1 file changed

+213
-5
lines changed
  • user/pages/03.commerce2/02.developer-guide/05.payments/10.code-recipes

1 file changed

+213
-5
lines changed

user/pages/03.commerce2/02.developer-guide/05.payments/10.code-recipes/docs.md

+213-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,217 @@ taxonomy:
44
category: docs
55
---
66

7-
! We need help filling out this section! Feel free to follow the *edit this page* link and contribute.
7+
If you want to write custom code to programatically manage payments, you can use these code recipes as a starting point.
8+
- **Create:**
9+
- [Payment gateway](#creating-a-payment-gateway)
10+
- [Payment method](#creating-a-payment-method)
11+
- [Payment](#creating-a-payment)
12+
- **Load:**
13+
- [Payment gateway](#loading-a-payment-gateway)
14+
- [Payment method](#loading-a-payment-method)
15+
- [Payment](#loading-a-payment)
16+
- **Manage payments:**
17+
- [Setting the payment gateway for an order](#setting-the-payment-gateway-for-an-order)
18+
- [Adding a refunded amount to an existing payment](#adding-a-refunded-amount-to-an-existing-payment)
19+
- [**Filter payment gateways available for an order**](#filter-payment-gateways-available-for-an-order)
820

9-
- CRUD operations for payments
10-
- theming/templates
11-
- payment events
12-
- describe Payment example module here or on separate page?
21+
### Creating a payment gateway
22+
Payment gateways are configuration entities that store the configuration for payment gateway plugins. The configuration keys will vary based on the payment gateway definition. The `Drupal\commerce_payment\Plugin\Commerce\PaymentGatewayBase` class defines `display_label`, `mode`, and `payment_method_types`. In this example, we've also added an `api_key` key.
23+
```php
24+
/**
25+
* id [String]
26+
* Primary key for this payment gateway.
27+
*
28+
* label [String]
29+
* Label for this payment gateway.
30+
*
31+
* weight [Integer]
32+
* The payment gateway weight.
33+
*
34+
* plugin [String]
35+
* Foreign key of the payment gateway plugin to use.
36+
*
37+
* configuration [Array]
38+
* The plugin configuration.
39+
*
40+
* conditions [Array]
41+
* The conditions that control gateway availability.
42+
*
43+
* conditionOperator [String] - [DEFAULT = AND]
44+
* The condition operator.
45+
*/
46+
47+
// Create the payment gateway.
48+
$payment_gateway = \Drupal\commerce_payment\Entity\PaymentGateway::create([
49+
'id' => 'my_example',
50+
'label' => "My example payment gateway",
51+
'weight' => 0,
52+
'plugin' => 'example_onsite',
53+
'configuration' => [
54+
'api_key' => '2342fewfsfs',
55+
'display_label' => 'Credit card test',
56+
'mode' => 'test',
57+
'payment_method_types' => ['credit_card'],
58+
],
59+
'conditions' => [
60+
[
61+
'plugin' => 'order_total_price',
62+
'configuration' => [
63+
'operator' => '<',
64+
'amount' => [
65+
'number' => '100.00',
66+
'currency_code' => 'USD',
67+
],
68+
],
69+
],
70+
],
71+
]);
72+
$payment_gateway->save();
73+
```
74+
75+
In this second example of payment gateway creation, we're separating the payment gateway plugin configuration from the creation of the payment gateway. This alternative approach works just the same but can result in slightly more readable code. Also, there may be times when you only want to update the configuration for an existing payment gateway.
76+
```php
77+
$payment_gateway = \Drupal\commerce_payment\Entity\PaymentGateway::create([
78+
'id' => 'manual',
79+
'label' => 'Manual example',
80+
'plugin' => 'manual',
81+
]);
82+
$payment_gateway->getPlugin()->setConfiguration([
83+
'display_label' => 'Cash on delivery',
84+
'instructions' => [
85+
'value' => 'Test instructions.',
86+
'format' => 'plain_text',
87+
],
88+
]);
89+
$payment_gateway->save();
90+
```
91+
92+
### Creating a payment method
93+
In this example, we assume that we have that the variable `$order` is an object of type `Drupal\commerce_order\Entity\OrderInterface`. In this example, the payment method will expire on Thursday, January 16th, 2020. To create a payment method that does not expire, omit the `expires` key or set it to 0; its default value is 0.
94+
```php
95+
$payment_method = Drupal\commerce_payment\Entity\PaymentMethod::create([
96+
'type' => 'credit_card',
97+
'payment_gateway' => 'example',
98+
'payment_gateway_mode' => 'test',
99+
'remote_id' => 'example123abc',
100+
'reusable' => TRUE,
101+
'is_default' => TRUE,
102+
// Thu, 16 Jan 2020.
103+
'expires' => '1579132800',
104+
'uid' => $order->getCustomerId(),
105+
'billing_profile' => $order->getBillingProfile(),
106+
]);
107+
$payment_method->save();
108+
```
109+
110+
### Creating a payment
111+
```php
112+
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $onsite_gateway */
113+
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
114+
115+
$payment = Drupal\commerce_payment\Entity\Payment::create([
116+
'type' => 'payment_default',
117+
'payment_gateway' => $onsite_gateway->id(),
118+
'order_id' => $order->id(),
119+
'amount' => $order->getTotalPrice(),
120+
'state' => 'completed',
121+
]);
122+
$payment->save();
123+
```
124+
125+
### Loading a payment gateway
126+
```php
127+
// Loading is based off of the primary key [String] that was defined when creating it.
128+
$payment_gateway = \Drupal\commerce_payment\Entity\PaymentGateway::load('manual');
129+
```
130+
131+
###Loading a payment method
132+
```php
133+
// Loading is based off of the primary key [Integer]
134+
// 1 would be the first one saved, 2 the next, etc.
135+
$payment_method = \Drupal\commerce_payment\Entity\PaymentMethod::load(1);
136+
```
137+
138+
Example: load user's reusable payment methods that have not yet expired for a given payment gateway, filtered by country.
139+
```php
140+
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway */
141+
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $user */
142+
$payment_methods = \Drupal::entityTypeManager()
143+
->getStorage('commerce_payment_method')
144+
->loadReusable($user, $payment_gateway, ['US', 'FR']);
145+
```
146+
147+
###Loading a payment
148+
```php
149+
// Loading is based off of the primary key [Integer]
150+
// 1 would be the first one saved, 2 the next, etc.
151+
$payment = \Drupal\commerce_payment\Entity\Payment::load(1);
152+
153+
```
154+
155+
### Setting the payment gateway for an order
156+
```php
157+
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
158+
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $example_payment_gateway */
159+
$order->set('payment_gateway', $example_payment_gateway);
160+
$order->save();
161+
```
162+
163+
### Adding a refunded amount to an existing payment
164+
```php
165+
/** @var \Drupal\commerce_payment\Entity\PaymentInterface $payment */
166+
$payment->setRefundedAmount(new Drupal\commerce_price\Price('15', 'USD'));
167+
$payemnt->save();
168+
```
169+
170+
### Filter payment gateways available for an order
171+
The payment module includes a `FilterPaymentGatewaysEvent` event that can be used whenever filtering available gateways using [Conditions](../../03.core/01.conditions) is not sufficient. In this example, we use the `data` field on `Order` entities to store a list of explicitly excluded payment gateways.
172+
173+
First, use the `data` field to store a payment gateway to be excluded.
174+
```php
175+
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
176+
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $example_payment_gateway */
177+
$order->setData('excluded_gateways', [$example_payment_gateway->id()]);
178+
$order->save();
179+
```
180+
181+
Next, implement the event subscriber in your custom module.
182+
```php
183+
<?php
184+
185+
namespace Drupal\my_custom_module\EventSubscriber;
186+
187+
use Drupal\commerce_payment\Event\FilterPaymentGatewaysEvent;
188+
use Drupal\commerce_payment\Event\PaymentEvents;
189+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
190+
191+
class FilterPaymentGatewaysSubscriber implements EventSubscriberInterface {
192+
193+
/**
194+
* {@inheritdoc}
195+
*/
196+
public static function getSubscribedEvents() {
197+
return [
198+
PaymentEvents::FILTER_PAYMENT_GATEWAYS => 'onFilter',
199+
];
200+
}
201+
202+
/**
203+
* Filters out payment gateways listed in an order's data attribute.
204+
*
205+
* @param \Drupal\commerce_payment\Event\FilterPaymentGatewaysEvent $event
206+
* The event.
207+
*/
208+
public function onFilter(FilterPaymentGatewaysEvent $event) {
209+
$payment_gateways = $event->getPaymentGateways();
210+
$excluded_gateways = $event->getOrder()->getData('excluded_gateways', []);
211+
foreach ($payment_gateways as $payment_gateway_id => $payment_gateway) {
212+
if (in_array($payment_gateway->id(), $excluded_gateways)) {
213+
unset($payment_gateways[$payment_gateway_id]);
214+
}
215+
}
216+
$event->setPaymentGateways($payment_gateways);
217+
}
218+
219+
}
220+
```

0 commit comments

Comments
 (0)