Jump to content
apeisa

Payment modules in ProcessWire

Recommended Posts

I am looking for some guidance about how to implement payment modules in ProcessWire. I am not looking for tutorial how to add paypal payment etc, I am thinking about in much more higher or in more abstract level. What I would like to achieve is some kind of "payment framework" of sorts. This is all pseudo code, but hopefully helps to understand what I am after:


// Payment form was submitted
if ($input->post->submit) {
  $payment = new Payment();
  $payment->method = "PayPal"; // ie. "AuthorizeNet" or "PayPal" etc...
  $payment->currency = "euro";

  // If simple one row payment...
  $payment->title = "Donation for new school";
  $payment->value = 200.2;

  // If multiple rows
  $payment->addRow("New schoolbooks", 190);
  $payment->addRow("Processing fees", 10.2);

  $payment->process();

  if ($payment->wasSuccessful()) {
    echo "Thank you very much";
  } else {
    echo "Sorry, it didn't work this time";
  }

}

I would love to use something like this. It has also been my number one reason that I haven't taken few hours here and there to implement more payment methods for my current shop module - those are just for the shop and impossible to use in other areas of PW. I would love to see more general way to manage payments.

This is by no means a simple task, since payments methods are all little bit different. Some have JS-embeds, others process on server, and others redirect to payment processor etc... So looking for ideas and feedback how we should approach this. Also if there is some general PHP lib doing this kind of stuff, using it would be nice too..?

Share this post


Link to post
Share on other sites

Did you have a look at how http://ci-merchant.org/ achieves that? I noticed that they support lots of gateways, I just don't know if they have different code for each one of them, or if they do it in a more abstract level as you want.

edit: hm, not that easy. There is a "Merchant-driver" class, and each payment gateway has it's own class that extends "Merchant-driver" or one of the other gateway classes. Some of them can get pretty complicated...

edit2: have a look at this one also https://github.com/adrianmacneil/omnipay

  • Like 1

Share this post


Link to post
Share on other sites

Maybe a "Payment Module" which handles all the complicated stuff behind.

So to take your example:

// Payment form was submitted
if ($input->post->submit) {
  $payment = $modules->get('PwPayment');
  $payment->method = "PayPal"; // ie. "AuthorizeNet" or "PayPal" etc...
  $payment->currency = "euro";
//...

There must be some abstract base class "Payment" that provides common methods and variables. Maybe an interface too to exaclty define which methods need to be implemented for the different Payments. Then each payment could have its own class extending the base Payment class.

Of course the actual implementation would still be hard because of the different ways each payment works. But with a pattern like this, the module could be used anywhere and always has all the implemented Gateways available.

Pseudo code:

<?php
//The Module
class PwPayment extends WireData implements Module {

protected Payment $payment = null;

//Overwerite the magic set method
public function __set($key, $value) {
  if ($key == 'method') {
    switch ($value) {
      case 'PayPal':
      $payment = new PaymentPayPal();
      break;
    }
  }
  return parent::__set();
}

public function ___process() {
  return $payment->process();  
}

}

//The abstract class
abstract class Payment {
  
  public function addJs();
  public function process();
  public function checkErrors();
}

//PayPal Implementation
class PaymentPayPal extends Payment {
//...
}


 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks guys! I think I will investigate that Omnipay and look into how PW wrapper for that would work!

Share this post


Link to post
Share on other sites

I've integrated both Stripe and PayPal into some PW sites and would be interested in a generalised payments setup for ProcessWire. I rather liked the way you added Payment support to your eCommerce module, apesia, but when I came to add payments for a subscription module I ended up creating parallel modules that could handle the different scenarios. 

  • Like 1

Share this post


Link to post
Share on other sites

I would love to see more abstracted way to handle payments. Payment Methods in shopping cart are nice, but too tied to shopping cart. I actually build one abstract class for payments few months back (and implemented one payment method using that class), but didn't get time to finish that. It's not that simple to find good balance on what to abstract, since there are different kind of methods for payments (processors where all the payment information are collected on payment processors site and then ones where processor just process the payment on background - and anything between).

Share this post


Link to post
Share on other sites

I usually keep the order info separate from the payment info. The payment info is mostly about the transaction with the service handling the actual payment and is linked in the database to the user and the order. I put failures and error messages in there too because now and then one needs to compare that to a customer's story.

Share this post


Link to post
Share on other sites

I agree about order, Steve. I think a payments abstract class should record the payment details and then orders (in a shopping setup), subscriptions, or donations can simply reference the payment with a page reference field.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...