Using a Payment Method

Collecting payment information from your users is just the initial step in the payment workflow. From there you will want to use the payment method to perform a variety of transactions in potentially different scenarios. This guide will help use your payment methods to transact against a gateway as efficiently as possible.

Supported transactions

Once you are collecting payment information from your customers you will most likely need to transact against the collected payment methods. Making a purchase is the most common type of transaction, but Spreedly supports a variety of other transactions if you need greater control of the purchasing process.

Spreedly supports the following transactions:

  • Purchase: Make a purchase with a given payment method against a gateway.
  • Authorize: Authorize a purchase (but do not transfer any funds) with a given payment method against a gateway.
  • Capture: Capture the funds previously reserved via an authorization.
  • Credit (Refund): Credit funds back to a payment method used in a previous transaction.
  • Void: Cancel out authorizations and, with some gateways, actual transactions within the first 24 hours.
  • Verify: Ask a gateway if a payment method is in good standing.

While Spreedly supports invoking these five major transaction types, it also requires support from the underlying gateway. A gateway’s support for each transaction can be found in the gateway docs.

Finalized capture and refund notifications

For most gateways, a successful response from a capture or credit (refund) request indicates that the request to perform these actions has successfully been received by the gateway, not that the transaction has been successfully processed. At the card network level, these actions are queued up and performed in batches at certain intervals. If you would like to receive confirmation that the action has been successfully performed through the card network, gateways generally provide a notification system that can be set up to confirm finalized transactions.

Verifying a card

Note: The Spreedly verify transaction is not related to the address verification system (AVS) or card verification value (CVV). Please read on for more details.

There may be times when you collect payment information from your users, but do not transact against that card until much later. It would be nice to know when you’re collecting the payment information if it is a chargeable card and available for purchases. Any issues would then be presented and rectified at the time of submission and not later at the time of purchase.

When dealing directly with a gateway this is often accomplished by doing an authorize against the card for some small amount (sometimes even a $0 auth is allowed), and then immediately voiding the auth. If the authorize succeeds you know the card is in good standing. Otherwise, it is not. On Spreedly, this auth/void verification step is encapsulated into a single verify transaction.

Behind the scenes, Spreedly performs an authorize and then a void. We try to charge the minimum amount the gateway will allow, and in the typical case the value is $1. Some gateways have a special API call we can use to verify a card. Other gateways allow a $0 authorization we can take advantage of as well.

If verify is supported, it will be listed in the Supported Operations section of the applicable Gateway Guide. If you do not see it listed on your preferred gateway, you may contact Support to review feasibility.

Retaining the payment method on success

A typical workflow is to use the iFrame to add a payment method, then trigger either a purchase, verify, or authorize. If the purchase, verify, or authorize is successful, you may then want to retain the payment method.

If this is your workflow, passing the retain_on_success parameter to the purchase, verify, or authorize call can save you from having to make another API call to do the retain. If the purchase, verify, or authorize succeeds, then the payment method is retained for you.

Note: In this scenario, the initial transaction response from the Spreedly API will show that the payment method’s storage_state is cached even if the transaction was successful. This is because the response shows a snapshot of the payment method at the time the transaction was executed. The storage_state will be updated to retained immediately after the transaction succeeds.


curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <retain_on_success>true</retain_on_success>
    </transaction>'


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.purchase_on_gateway("LlkjmEk0xNkcWrNixXa1fvNoTP4", "56wyNnSmuA6CWYP7w0MiYCVIbW6",
                        4432, retain_on_success: true)

Continue caching the cvv

By default, after a transaction is run with a credit card the cvv is then immediately deleted. There may be some instances in which you want to hold on to that cvv a little longer to be able to send a card to multiple endpoints.

If this is your workflow, passing the continue_caching parameter to the transaction will help. The cvv will still automatically be deleted after a few minutes.


curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <continue_caching>true</continue_caching>
    </transaction>'


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.purchase_on_gateway("LlkjmEk0xNkcWrNixXa1fvNoTP4", "56wyNnSmuA6CWYP7w0MiYCVIbW6",
                        4432, continue_caching: true)

Reference purchases

This is a seldom used feature of some gateways. Almost all of the time, retaining a credit card is a better option since a retained card can be used on any gateway in the future.

Reference purchases are a way to reuse the payment method from a previous (successful) transaction in a whole new purchase, which can result in lower decline rates. They are also an option if you no longer have access to the payment method’s CVV, but your gateway requires one to be submitted. A reference purchase can reuse all the payment information from the original method, including the CVV. One of the main downsides is that the reference purchase can only be used with that one gateway account.

You can see whether the gateway you’re interacting with allows references by looking at the supports_reference_purchase property in this list of gateways. We also show that ability in the body of the response when you create a gateway.

Adding transaction details

There are a variety of order details you may want to pass on to the gateway as part of a transaction. They include:

Order id

For purchase, authorize, capture, credit, and void calls, you can specify an order_id like so:


curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <order_id>44837</order_id>
      </transaction>'


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.purchase_on_gateway("LlkjmEk0xNkcWrNixXa1fvNoTP4", "56wyNnSmuA6CWYP7w0MiYCVIbW6",
                        4432, order_id: "44837")

We’ll pass this order_id to the gateway for you. If you don’t specify an order_id, we’ll pass the token of the transaction as the order_id.

Description

For purchase, authorize, capture, credit, and void calls, you can specify a description like so:


curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <description>Apparel Purchase</description>
    </transaction>'


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.purchase_on_gateway("LlkjmEk0xNkcWrNixXa1fvNoTP4", "56wyNnSmuA6CWYP7w0MiYCVIbW6",
                        4432, description: "Apparel Purchase")

We’ll pass this description to the gateway if the gateway supports it. If you don’t specify a description, we’ll just leave it blank.

Customer IP address

For purchase, authorize, capture, credit, and void calls, you can optionally specify the ip address of the customer like so:


curl https://core.spreedly.com/v1/transactions/KS3oZgWXCfFeirK16anYbijLxR/credit.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <ip>192.168.0.4</ip>
      </transaction>'


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.refund_transaction("KS3oZgWXCfFeirK16anYbijLxR", ip: "192.168.0.4")

We’ll pass this ip address to the gateway for you.

Customer email

Many gateways allow passing an email address when running a transaction so that the transaction is associated with that email address in the gateway’s backend. While Spreedly allows you to associate an email address with a payment method when the payment method is created, you may want to override that for a later transaction, or the email address may not be available when the payment method is created. If you pass in an email address with the transaction, it will override the email address (if any) that is on the payment method, and Spreedly will pass it on to your gateway when possible:


curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <order_id>44837</order_id>
        <email>bob@example.com</email>
      </transaction>'


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.purchase_on_gateway("LlkjmEk0xNkcWrNixXa1fvNoTP4", "56wyNnSmuA6CWYP7w0MiYCVIbW6",
                        4432, email: "bob@example.com")

Shipping Address Override

When creating payment methods, you have the option to save a shipping address with that payment method. However, in some cases users may want to use a different shipping address for a particular order while still maintaining a default shipping address. To use a different shipping address on a transaction without updating the shipping address associated with a particular payment method, just send it as part of a transaction like so:


curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <shipping_address>
          <name>John Doe</name>
          <address1>123 Main St.</address1>
          <address2>Suite 100</address2>
          <city>City</city>
          <state>State</state>
          <zip>45678</zip>
          <country>US</country>
          <phone>123-456-7890</phone>
       </shipping_address>
      </transaction>'

Gateway Specific Fields

A gateway-specific field (GSF) is a unique optional field that some gateways need for certain customized options. To send a GSF along with your Purchase request to a gateway, it should be nested under gateway_specific_fields, and under the gateway’s name, i.e. gateway_type. This format lets customers set up a generic structure for a request that could be sent to one of a number of gateways by allowing GSFs for multiple gateways to be included in the same request. Spreedly will handle sending the right GSFs to the respective gateway, without a merchant needing to alter the body of the request. See the example below:


curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <gateway_specific_fields>
          <stripe>
            <sample_field>123</sample_field>
          </stripe>
        </gateway_specific_fields>
      </transaction>'

Matching with a gateway transaction

You’ll notice an attribute named gateway_transaction_id on the returned transaction after you perform an operation such as a purchase or an authorization. The gateway_transaction_id is the transaction ID your gateway uses to identify the transaction within their system. This attribute can help you to correlate a Spreedly transaction with the transaction in your gateway.

We’ve implemented this functionality for a number of the more popular gateways. If you don’t see a gateway_transaction_id in your transactions, contact support@spreedly.com so we can add support for this feature to your gateway.

Voiding and Refunding

Most gateways will decline a refund call if the transaction hasn’t settled at the merchant account. They’ll typically allow a void in that case. For this reason, most customers attempt a void first. If it’s successful, they’re done. If the void transaction fails for any reason, they attempt a refund.