- Documentation >
- Commerce >
- Payment management >
- Extend Payment
Extend Payment
You can extend your Payment module implementation:
- by creating a custom payment method type
- by attaching custom data to a payment
You can also customize the payment processing workflow.
Create custom payment method type
If your application needs payment methods of other type than the default offline
one, or ones offered by Payum, you can create custom payment method types.
Code samples below show how this could be done if your organization wants to use PayPal independently.
Gateway integration requirement
Ibexa DXP doesn't come with gateway redirects. Whether you're an integrator or an end customer, it's your responsibility to implement payment gateway integration.
Define custom payment method type
Create a PHP definition of the payment method type.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | <?php
declare(strict_types=1);
namespace App\Payment;
use Ibexa\Contracts\Payment\PaymentMethod\Type\TypeInterface;
final class PayPal implements TypeInterface
{
public function getIdentifier(): string
{
return 'paypal';
}
public function getName(): string
{
return 'PayPal';
}
}
|
Make sure that getName()
returns a human-readable name of the payment method type, the way you want it to appear on the list of available payment method types.
Now, register the definition as a service:
| services:
App\Payment\PayPal:
tags:
name: ibexa.payment.payment_method.type
alias: paypal
|
As an alternative, instead of creating a custom class, you can use a built-in type factory to define the payment method type in the service definition file:
| services:
app.payment.type.paypal:
class: Ibexa\Contracts\Payment\PaymentMethod\Type\TypeInterface
factory: [ '@Ibexa\Contracts\Payment\PaymentMethod\Type\TypeFactoryInterface', 'createType' ]
arguments:
$identifier: 'paypal'
$name: 'PayPal'
tags:
- name: ibexa.payment.payment_method.type
alias: paypal
|
At this point a custom payment method type should be visible in the user interface.
Create a corresponding form type:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | <?php
declare(strict_types=1);
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
final class PayPalOptionsType extends AbstractType
{
public function buildForm(
FormBuilderInterface $builder,
array $options
): void {
$builder->add('base_url', UrlType::class, [
'constraints' => [new NotBlank()],
]);
// ...
}
}
|
Next, create a mapper that maps the information that the user inputs in the form into attribute definition.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | <?php
declare(strict_types=1);
namespace App\Form\Type;
use Ibexa\Contracts\Payment\PaymentMethod\Type\OptionsFormMapperInterface;
use Symfony\Component\Form\FormBuilderInterface;
final class OptionsFormMapper implements OptionsFormMapperInterface
{
public function createOptionsForm(
string $name,
FormBuilderInterface $builder,
array $context = []
): void {
$builder->add($name, PayPalOptionsType::class);
}
}
|
Then, register OptionsFormMapper
a service:
| services:
App\Form\Type\OptionsFormMapper:
tags:
- name: ibexa.payment.payment_method.options.form_mapper
type: paypal
|
Create options validator
You might want to make sure that data provided by the user is validated.
To do that, create an options validator that checks user input against the constraints and dispatches an error when needed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | <?php
declare(strict_types=1);
namespace App\Form\Type;
use Ibexa\Contracts\Core\Options\OptionsBag;
use Ibexa\Contracts\Payment\PaymentMethod\Type\OptionsValidatorError;
use Ibexa\Contracts\Payment\PaymentMethod\Type\OptionsValidatorInterface;
final class UrlOptionValidator implements OptionsValidatorInterface
{
public function validateOptions(OptionsBag $options): array
{
$errors = [];
if (empty($options->get('base_url'))) {
$errors[] = new OptionsValidatorError('base_url', 'Base URL cannot be blank');
}
// Add gateway implementation here
return $errors;
}
}
|
Then, register the validator as a service:
| services:
App\Form\Type\OptionsValidator:
tags:
- name: ibexa.payment.payment_method.options.validator
type: paypal
|
Restart application
Shut down the application, clear browser cache, and restart the application.
Then, try creating a payment of the new type.
Attach custom data to payments
When you create a payment, you can attach custom data to it, for example, you can pass an invoice number or a proprietary transaction identifier.
You add custom data by using the setContext
method:
| // Create a new payment
$context = [
'transaction_id' => '5e5fe187-c865-49£2-b407-a946fd7b5be0',
];
$paymentCreateStruct = new PaymentCreateStruct(
$this->paymentMethodService->getPaymentMethodByIdentifier('bank_transfer_EUR'),
$this->orderService->getOrder(135),
new Money\Money(100, new Money\Currency('EUR'))
);
$paymentCreateStruct->setContext(new ArrayMap($context));
|
Then, you retrieve it with the getContext
method:
| $paymentIdentifier = '4ac4b8a0-eed8-496d-87d9-32a960a10629';
$payment = $this->paymentService->getPaymentByIdentifier($paymentIdentifier);
|