Collect Your First Payment with a Card Reader
In addition to collecting payments via text messaging, Podium lets you accept in-person credit and debit card payments using a Podium reader. Using card readers in conjunction with Podium means that you can:
- Consolidate all of your payment methods into one platform.
- Automate text and email receipts to all customers.
Podium card reader availability
Podium card readers are currently only available in the United States.
At a glance
Invoices enable a business to request and receive payments via Podium. Podium readers are the physical terminal that allows the business to collect payments for card-present transactions.
Podium's Invoice API allows you to manage the complete lifecycle of requesting payment, issuing refunds, and reconciling payments received back into your system of record.
You can use these endpoints to do things like:
- Create a new invoice to display on a designated payment reader.
- Update an invoice to either cancel the invoice entirely or refund an amount (full or partial).
- Retrieve and reconcile payments completed on invoices.
A Podium card reader deployment consists of four main components:
- Your web-based or mobile application
- Your backend
- Podium Invoice API
- A Podium card reader
What you'll need
- An active Podium location
- Client ID and Secret for OAuth access token
- A Podium card reader
Test Card Numbers
Card Number | Brand | CVC | Date |
---|---|---|---|
4242424242424242 | Visa | Any 3 digits | Any future date |
5555555555554444 | Mastercard | Any 3 digits | Any future date |
Create an invoice
To request a payment to display on a Podium card reader, you will need to provide the following required details:
- Location UID. The unique identifier of the Podium account associated to the merchant's Payment reader that can be found via the Podium Locations API.
- Reader UID. The unique identifier of the physical hardware of the card reader.
- Customer Name. The first and last name of the recipient of the payment request. (For example, "John Doe")
- Channel Identifier. The email or phone number of the end consumer. This is used to send a receipt and additional messages after the transaction. (For example, a request to leave an online review on a review platform like Google or Facebook).
- Line Item(s). A minimum of one line item is required. Each line item will consist of detail an amount (required) and a description (optional). An example of the description and amount: Recliner, 20000.

An invoice request via a Podium payment reader
Create an invoice to the payment reader
curl --request POST \
--url https://api.podium.com/v4/invoices \
--header 'Content-Type: application/json' \
--header 'podium-version: 2021.4.1' \
--data '{"locationUid":"9483748s-3a1c-5537-a31b-442ca560593d","customerName":"John Smith","channelIdentifier":"[email protected]","lineItems":[{"Amount":"20000","Description":"Recliner"}],"readerUid":"46525as-3a1c-5537-a31b-442ca560593d","invoiceNumber":"IN-3240ASD"}'
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://api.podium.com/v4/invoices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["podium-version"] = '2021.4.1'
request["Content-Type"] = 'application/json'
request.body = "{\"locationUid\":\"9483748s-3a1c-5537-a31b-442ca560593d\",\"customerName\":\"John Smith\",\"channelIdentifier\":\"[email protected]\",\"lineItems\":[{\"Amount\":\"10000\",\"Description\":\"Chair\"}],\"readerUid\":\"46525as-3a1c-5537-a31b-442ca560593d\",\"invoiceNumber\":\"IN-3240ASD\"}"
response = http.request(request)
puts response.read_body
const options = {
method: 'POST',
headers: {'podium-version': '2021.4.1', 'Content-Type': 'application/json'},
body: JSON.stringify({
locationUid: '9483748s-3a1c-5537-a31b-442ca560593d',
customerName: 'John Smith',
channelIdentifier: '[email protected]',
lineItems: [{Amount: '10000', Description: 'Chair'}],
readerUid: '46525as-3a1c-5537-a31b-442ca560593d',
invoiceNumber: 'IN-3240ASD'
})
};
fetch('https://api.podium.com/v4/invoices', options)
.then(response => console.log(response))
.catch(err => console.error(err));
import requests
url = "https://api.podium.com/v4/invoices"
payload = {
"locationUid": "9483748s-3a1c-5537-a31b-442ca560593d",
"customerName": "John Smith",
"channelIdentifier": "[email protected]",
"lineItems": [
{
"Amount": "10000",
"Description": "Chair"
}
],
"readerUid": "46525as-3a1c-5537-a31b-442ca560593d",
"invoiceNumber": "IN-3240ASD"
}
headers = {
"podium-version": "2021.4.1",
"Content-Type": "application/json"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
Refund an invoice
Occasionally, you may need to issue refunds. For example, if your customer receives the wrong product or isn’t satisfied with the service you’ve provided. You can quickly process refunds by making a request to the Invoices API.

Refunding the payment of an invoice
Note
A payment needs to occur on an invoice in order to request a refund. To test payments, reference Podium's test account information.
The following parameters are required to request a refund to the payment within an invoice.
- Invoice UID. The internal unique identifier we ascribe to each invoice sent through Podium.
- Location UID. The unique identifier of the Podium account associated to the merchant's payment reader that can be found via the Podium Locations API.
- Reason. Available options for reason include duplicate, fraudulent, requested_by_customer, or other.
- Amount. The amount for the refund represented in cents.
curl --request POST \
--url https://api.podium.com/v4/invoices/d011ed93-535d-57f8-9da6-d5323e226949/refund \
--header 'Content-Type: application/json' \
--header 'podium-version: 2021.4.1' \
--data '{"locationUid":"9483748s-3a1c-5537-a31b-442ca560593d","reason":"other","amount":1000,"paymentUid":"d011ed93-535d-57f8-9da6-d5323e226338","note":"charged twice for same service"}'
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://api.podium.com/v4/invoices/d011ed93-535d-57f8-9da6-d5323e226949/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["podium-version"] = '2021.4.1'
request["Content-Type"] = 'application/json'
request.body = "{\"locationUid\":\"9483748s-3a1c-5537-a31b-442ca560593d\",\"reason\":\"other\",\"amount\":1000,\"paymentUid\":\"d011ed93-535d-57f8-9da6-d5323e226338\",\"note\":\"charged twice for same service\"}"
response = http.request(request)
puts response.read_body
const options = {
method: 'POST',
headers: {'podium-version': '2021.4.1', 'Content-Type': 'application/json'},
body: JSON.stringify({
locationUid: '9483748s-3a1c-5537-a31b-442ca560593d',
reason: 'other',
amount: 1000,
paymentUid: 'd011ed93-535d-57f8-9da6-d5323e226338',
note: 'charged twice for same service'
})
};
fetch('https://api.podium.com/v4/invoices/d011ed93-535d-57f8-9da6-d5323e226949/refund', options)
.then(response => console.log(response))
.catch(err => console.error(err));
import requests
url = "https://api.podium.com/v4/invoices/d011ed93-535d-57f8-9da6-d5323e226949/refund"
payload = {
"locationUid": "9483748s-3a1c-5537-a31b-442ca560593d",
"reason": "other",
"amount": 1000,
"paymentUid": "d011ed93-535d-57f8-9da6-d5323e226338",
"note": "charged twice for same service"
}
headers = {
"podium-version": "2021.4.1",
"Content-Type": "application/json"
}
response = requests.request("POST", url, json=payload, headers=headers)
print(response.text)
The id returned in the response is an MD5 hash of the contact’s lowercase email address. You can learn more about that here.
Check the invoice status
An invoice will have any of the following statuses:
- Pending. No payment has been completed on the invoice.
- Refunded. When the full or a partial amount of the payment has been returned to the end consumer.
- Paid. When the payment request has been completed and the full amount of all line items within an invoice are paid in full.
- Canceled. The status for an invoice that is voided and no longer available to collect payments. If the end consumer attempts to make a payment, they will be unable due to the canceled status.
Since we just updated the invoice status with a refund amount, we should expect to see that status as "refunded" in the response.
curl --request GET \
--url https://api.podium.com/v4/invoices/d011ed93-535d-57f8-9da6-d5323e226949 \
--header 'Content-Type: application/json' \
--header 'podium-version: 2021.4.1' \
--data '{"locationUid":"485red93-535d-57f8-9da6-d5323e226949"}'
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://api.podium.com/v4/invoices/d011ed93-535d-57f8-9da6-d5323e226949")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["podium-version"] = '2021.4.1'
request["Content-Type"] = 'application/json'
request.body = "{\"locationUid\":\"485red93-535d-57f8-9da6-d5323e226949\"}"
response = http.request(request)
puts response.read_body
const options = {
method: 'GET',
headers: {'podium-version': '2021.4.1', 'Content-Type': 'application/json'},
body: JSON.stringify({locationUid: '485red93-535d-57f8-9da6-d5323e226949'})
};
fetch('https://api.podium.com/v4/invoices/d011ed93-535d-57f8-9da6-d5323e226949', options)
.then(response => console.log(response))
.catch(err => console.error(err));
import requests
url = "https://api.podium.com/v4/invoices/d011ed93-535d-57f8-9da6-d5323e226949"
payload = {"locationUid": "485red93-535d-57f8-9da6-d5323e226949"}
headers = {
"podium-version": "2021.4.1",
"Content-Type": "application/json"
}
response = requests.request("GET", url, json=payload, headers=headers)
print(response.text)
Reconcile payments
Similar to checking an invoice status, when the invoice status is paid, refunded, or canceled, you can use the updated information of the payment and invoice to sync with your system of record. Reconciliation can be done in two ways.
Invoices API
This is the same process as retrieving an invoice through the Get Invoices API as seen above.

Payment received
Invoices Webhook
If your system is set up to be able to listen for webhooks, you can use the Invoice Webhook Events to listen for updates when an invoice is paid.
Congratulations!
Congratulations, you've successfully created an invoice, made a refund to a payment, and then retrieved or listened for its status to reconcile the payment with your system of record.
Updated about 2 years ago