Skip to content

Extending the Plugin

schmittjoh edited this page Sep 17, 2010 · 4 revisions

Adding Payment Methods

The only method that currently ships with the plugin is PayPal (Express Checkout); however, you can easily add more payment methods as you need them. In order to do so, you need to perform the following steps:

1. Add the data container for your payment method:

Either you can add the container in your existing schema.yml, or you can simply create a new *.yml file in your config/doctrine/ directory. The data container must contain all fields which are necessary for the payment method to process transactions (approve, deposit, etc.). A payment container for credit card payment might look something like the following:

myCreditCardPaymentData:
  inheritance:
    extends: PaymentData
    type: column_aggregation
    keyField: method_class_name
    keyValue: myCreditCardPaymentMethod
  columns:
    cc_number: string(16)
    cc_holder: string(50)
    cc_expires: string(6)
    cc_cvc: string(5)
    cc_authorization_code: string(50)

2. Add the payment method class:

The payment method class processes the transactions which are performed on payments. This additional abstraction is wanted in order to separate the persistence layer from the payment method. The payment method class must implement the jmsPaymentMethodInterface (alternatively you can extend jmsPaymentMethod which implements the interface for you), and its constructor must not require any arguments. The class for creditcard payment from above, might look like this:

// myCreditCardPaymentMethod.class.php
class myCreditCardPaymentMethod extends jmsPaymentMethod
{
  public function __construct()
  {
    // load some API libraries required for the payment service provider
  }

  public function approve(jmsPaymentMethodData $data, $retry = false)
  {
    // you can access all data of the payment container via $data['fieldName']
    $ccNumber = $data['cc_number'];

    // contact the API and perform the approve transaction
    // if there goes something wrong, you need to throw an exception here
    // see the exceptions directory for a list of available exceptions

    // set the processed amount (this does not necessarily have to be the requested amount)
    $data->setProcessedAmount($amountReceivedFromPaymentServiceProvider);

    // update any data (e.g. the authorization code)
    $data['cc_authorization_code'] = $authCodeFromPaymentServiceProvider;
  }

  public function deposit(jmsPaymentMethodData $data, $retry = false)
  {
    // contact the API of the payment service provider, and deposit the amount
  }
}

3. Rebuild the Model

If you are still in development phase, you can rebuild the model by running php symfony doctrine:build --all --and-load. If you are already in production, the process is a bit more complicated since you cannot simply drop the existing database, and recreate it; see the Doctrine Manual for suggestions on how to do this.

4. Use the New Payment Method

Now, you can use the newly added payment method to process payments:

// in a real world scenario, the payment data container should come from a form
$payment = Payment::create(99.95, 'EUR', new myCreditCardPaymentData());

// this will create an instance of myCreditCardPaymentMethod (there will always be only one
// instance of each payment method), and call approve() on it.
$payment->performTransaction(FinancialTransaction::TYPE_APPROVE);