WooCommerce 2.6 introduced an API for storing and managing payment tokens for gateways. Users can also manage these tokens from their account settings and choose from saved payment tokens on checkout.
This guide offers a few useful tutorials for using the new API as well as all the various methods available to you.
## Tutorials
### Adding Payment Token API Support To Your Gateway
We'll use the Simplify Commerce gateway in some of these examples.
#### Step 0: Extending The Correct Gateway Base
WooCommerce ships with two base classes for gateways. These classes were introduced along with the Token API in 2.6. They are `WC_Payment_Gateway_CC` (for credit card based tokens) and `WC_Payment_Gateway_eCheck` (for eCheck based tokens). They contain some useful code for generating payment forms on checkout and should hopefully cover most cases.
You can also implement your own gateway base by extending the abstract `WC_Payment_Gateway` class, if neither of those classes work for you.
Since Simplify deals with credit cards, we extend the credit card gateway.
We need to tell WooCommerce our gateway supports tokenization. Like other gateways features, this is defined in a gateway's `__construct` in an array called `supports`.
#### Step 2: Define A Method For Adding/Saving New Payment Methods From "My Account"
The form handler that is run when adding a new payment method from the "my accounts" section will call your gateway's `add_payment_method` method.
After any validation (i.e. making sure the token and data you need is present from the payment provider), you can start building a new token by creating an instance of one of the following classes: `WC_Payment_Token_CC` or `WC_Payment_Token_eCheck`. Like gateways, you can also extend the abstract `WC_Payment_Token` class and define your own token type type if necessary. For more information on all three of these classes and their methods, see further down below in this doc.
Since Simplify uses credit cards, we will use the credit card class.
`$token = new WC_Payment_Token_CC();`
We will use various `set_` methods to pass in information about our token. To start with we will pass the token string and the gateway ID so the token can be associated with Simplify.
$token->set_gateway_id( $this->id ); // `$this->id` references the gateway ID set in `__construct`
```
At this point we can set any other necessary information we want to store with the token. Credit cards require a card type (visa, mastercard, etc), last four digits of the card number, an expiration month, and an expiration year.
In most cases, you will also want to associate a token with a specific user:
`$token->set_user_id( get_current_user_id() );`
Finally, we can save our token to the database once the token object is built.
`$token->save();`
Save will return `true` if the token was successfully saved, and `false` if an error occurred (like a missing field).
#### Step 3: Save Methods On Checkout
WooCommerce also allows customers to save a new payment token during the checkout process in addition to "my account". You'll need to add some code to your gateways `process_payment` function to make this work correctly.
To figure out if you need to save a new payment method you can check the following POST field which should return `true` if the "Save to Account" checkbox was selected.
`wc-{$gateway_id}-new-payment-method`
If you have previously saved tokens being offered to the user, you can also look at `wc-{$gateway_id}-payment-token` for the value `new` to make sure the "Use a new card" / "Use new payment method" radio button was selected.
Once you have found out that a token should be saved you can save a token in the same way you did in Step 2, using the `set_` and `save` methods.
#### Step 4: Retrieve The Token When Processing Payments
You will need to retrieve a saved token when processing a payment in your gateway if a user selects one. This should also be done in your `process_payment` method.
You can check if an existing token should be used with a conditional like the following:
// Token user ID does not match the current user... bail out of payment processing.
if ( $token->get_user_id() !== get_current_user_id() ) {
// Optionally display a notice with `wc_add_notice`
return;
}
```
Once you have loaded the token and done any necessary checks, you can get the actual token string (to pass to your payment provider) by using
`$token->get_token()`.
### Creating A New Token Type
You can extend the abstract WC_Payment_Token class and create a new token type If the provided eCheck and CC token types do not satisfy your requirements. There are a few things you need to include if you do this.
#### Step 0: Extend WC_Payment_Token And Name Your Type
Start by extending WC_Payment_Token and providing a name for the new type. We'll look at how the eCheck token class is built since it is the most basic token type shipped in WooCommerce core.
class WC_Payment_Token_eCheck extends WC_Payment_Token {
/** @protected string Token Type String */
protected $type = 'eCheck';
}
```
The name for this token type is 'eCheck'. The value provided in `$type` needs to match the class name (i.e: `WC_Payment_Token_$type`).
#### Step 1: Provide A Validate Method
Some basic validation is performed on a token before it is saved to the database. `WC_Payment_Token` checks to make sure the actual token value is set, as well as the `$type` defined above. If you want to validate the existence of other data (eChecks require the last 4 digits for example) or length (an expiry month should be 2 characters), you can provide your own `validate()` method.
Validate should return `true` if everything looks OK, and false if something doesn't.
Always make sure to call `WC_Payment_Token`'s validate method before adding in your own logic.
#### Step 2: Provide get\_ And set\_ Methods For Extra Data
You can now add your own methods for each piece of data you would like to expose. Handy functions are provided to you to make storing and retrieving data easy. All data is stored in a meta table so you do not need to make your own table or add new fields to an existing one.
Provide a `get_` and `set_` method for each piece of data you want to capture. For eChecks, this is "last4" for the last 4 digits of a check.
That's it! These meta functions are provided by [WC_Data](https://github.com/woothemes/woocommerce/blob/trunk/includes/abstracts/abstract-wc-data.php).
#### Step 3: Use Your New Token Type
You can now use your new token type, either directly when building a new token
or it will be returned when using `WC_Payment_Tokens::get( $token_id )`.
## Classes
### WC_Payment_Tokens
This class provides a set of helpful methods for interacting with payment tokens. All methods are static and can be called without creating an instance of the class.
Returns a token object for the token that is marked as 'default' (the token that will be automatically selected on checkout). If a user does not have a default token/has no tokens, this function will return null.
Orders can have payment tokens associated with them (useful for subscription products and renewing, for example). You can get a list of tokens associated with this function. Alternatively you can use `WC_Order`'s '`get_payment_tokens()` function to get the same result.
Makes the provided token (`$token_id`) the provided user (`$user_id`)'s default token. It makes sure that whatever token is currently set is default is removed and sets the new one.
`set_` methods **do not** update the token in the database. You must call `save()`, `create()` (new tokens only), or `update()` (existing tokens only).
#### validate()
Makes sure the credit card token has the last 4 digits stored, an expiration year in the format YYYY, an expiration month with the format MM, the card type, and the actual token.
Set the credit card type. This is a freeform text field, but the following values can be used and WooCommerce will show a formatted label New labels can be added with the `woocommerce_credit_card_type_labels` filter.
`set_` methods **do not** update the token in the database. You must call `save()`, `create()` (new tokens only), or `update()` (existing tokens only).
#### validate()
Makes sure the eCheck token has the last 4 digits stored as well as the actual token.
You should not use `WC_Payment_Token` directly. Use one of the bundled token classes (`WC_Payment_Token_CC` for credit cards and `WC_Payment_Token_eCheck`). You can extend this class if neither of those work for you. All the methods defined in this section are available to those classes.
`set_` methods **do not** update the token in the database. You must call `save()`, `create()` (new tokens only), or `update()` (existing tokens only).
Set the gateway associated with the token. This should match the "ID" defined in your gateway. For example, 'simplify_commerce' is the ID for core's implementation of Simplify.
Toggle a tokens 'default' flag. Pass true to set it as default, false if its just another token. This **does not** unset any other tokens that may be set as default. You can use `WC_Payment_Tokens::set_users_default()` to handle that instead.
Does a check to make sure both the token and token type (CC, eCheck, ...) are present. See `WC_Payment_Token_CC::validate()` or `WC_Payment_Token_eCheck::validate()` for usage.
#### read( $token_id )
Load an existing token object from the database. See `WC_Payment_Tokens::get()` which is an alias of this function.
Update an existing token. This will take any changed fields (`set_` functions) and actually save them to the database. Returns true or false depending on success.
This will create a new token in the database. So once you build it, create() will create a new token in the database with the details. Returns true or false depending on success.
`save()` can be used in place of `update()` and `create()`. If you are working with an existing token, `save()` will call `update()`. A new token will call `create()`. Returns true or false depending on success.