Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
POC only, DO NOT MERGE
Objective
Provide a new way for gateways to pass transaction data around throughout the payment, capture, and refund processes that's more reliable and testable, and cut down the size of our gateway classes.
Problem
Currently, transaction data is added directly to
WC_Order
objects by assigning new properties that often become their ownstdClass
objects which hold various bits of data. This can be credit card information or previous transaction details in the case of refunds. Historically, this has been a fine way to make important data available before and after calling a gateway's API. However, this may not to be so reliable in the future as we've seen with WooCommerce 3.0 compatibility and the move away from directly accessingWC_Order
properties.Solution
This PR introduces transaction objects. The purpose here is to decouple our gateway-specific data from
WC_Order
and have a consistent set of objects that are passed around instead, with the order merely being one of many properties associated with a single transaction. In this PR you will see a few familiar transaction types:All of these types would have a set of common properties accessible via getters and setters, which gateways would set as they become available, like
transaction_id
, and get as needed when adding order notes, etc... Right now these are mostly based on the meta we currently save to orders, as well as what's available via the Shopify APIPayment Methods
Another object added here is payment method. These would live inside the transaction object for any transaction type that requires payment information. Like transactions themselves, these would have getters and setters specific to their type, like
set_csc()
orset_check_number()
. One of the biggest benefits here is cleaning up some of the logic within the gateway classes surrounding credit cards vs. eChecks, keep the transaction objects themselves clear of specific payment types, as well as autofilling a lot of these properties if a token is present.Implementation
Within
process_payment()
, we could simply call a method such as$transaction = $this->create_payment_transaction()
, which would generate a new transaction object, which would be overrideable by the concrete gateway in case they need their own properties. We'd then go about setting various properties likeamount
,currency
, etc...In the case of direct payment transactions, we could similarly generate a payment method object and set it's properties like so:
Then add that to the trasaction object:
$transaction->set_payment_method( $payment_method );
All of this fantastic data would then be available down the line as we make API calls:
The Future
For now these would live and die only during the payment/capture/refund/void process, but eventually they could handle storing data via a
save()
method. This could be order meta as we do now, or if we wanted to store each transaction in a custom table down the line. With that we could extend the order admin with a more detailed list of transaction events, or make each transaction available via the REST API like Shopify.Eventually this could be a candidate for a core contribution if dealing with transactions in this manner proves useful.
What do y'all think? Any glaring problems or omissions you see here? I would love some feedback before going any further with actual gateway implementation.