Customer
A customer resource instance represents a customer account with the shop. Customer accounts store contact information for the customer, saving logged-in customers the trouble of having to provide it at every checkout. For security reasons, the customer resource instance does not store credit card information. Customers will always have to provide this information at checkout.
The customer resource instance also stores some additional information about the customer for the benefit of the shop owner, including: the number of orders, the amount of money s/he has spent and number of orders s/he has made throughout his/her history with the shop as well as the shop owner's notes and tags for the customer.
Validating customers
Before creating a new customer (either separately or as part of an order) it needs to be checked if the customer already exists within Flickrocket as follows:
GET /api/customers.json?email=someone@somewhere.com&password=MyClearTextPassword
The GET returns the customer if the email and password match and the customer exists. If the customer exists but the password doesn't match, the following error is returned:
{
"error" : "Customer found but password does not match."
String of error message.
"error_code" : -1
Code of error message.
"companies" : ["Master Video","Big foot planet"]
List of companies from which the customer has ordered. Only returned for error code -1.
}
If the customer doesn't exist, the returned data is empty:
{}
Note: Make sure to use always HTTPS when transferring passwords and tokens.
Keeping customer email and password in sync
Due to the customer access via the central player instance and the fact that a customer might have purchased content from multiple shops, it is extremely important that any email and password changes are synchonized at any time. This is done by sending a PUT identifying the user by his token and updating the email and/or password (don't forget password_confirmation) data.
Pre-authenticated login
Let's say you are the owner of a successful website forum. All of your users must log in to the forum to contribute. Members of your forum can then purchase content through your FlickRocket store. Unfortunately, your users have to log in to the forum first and then log in to your FlickRocket store before they can purchase.
Pre-authenticated login is for store owners who have a separate website and a FlickRocket store. It redirects users from the website to the FlickRocket store and seamlessly logs them in with the same email address they used to sign up for the original website. If no account with that email address exists yet, one is created. There is no need to synchronize any customer databases.
Step 1: Encode your customer information using JSON
The customer information is represented as a hash which must contain at least (A) the email address of the customer and his password or (B) the customer's token. You can also include the customer's first name, last name or several shipping addresses. Optionally, you can include an IP address of the customer's current browser session.
A minimal example, containing all required fields, might look like this:
{
email: "bob@somewhere.com",
password: "SuperSecretPassword"
}
or
{
customer_token: "TCMJEOTSBEVTDLFU"
}
An example containing some optional fields might look like this:
{
email: "bob@somewhere.com",
password: "SuperSecretPassword",
first_name: "Bob",
last_name: "Bobsen",
identifier: "bob123",
remote_ip: "107.20.160.121",
return_to: "https://shop.yourstore.com/some_specific_page",
addresses: [{
address1: "123 Oak St",
city: "Ottawa",
country: "Canada",
first_name: "Bob",
last_name: "Bobsen",
phone: "555-1212",
province: "Ontario",
zip: "123 ABC",
province_code: "ON",
country_code: "CA",
default: true
}]
}
By default, the shop's player page is presented. If you want your users to see a specific page of your FlickRocket store, you can use the "return_to" field for this.
Step 2. Encrypt the JSON data using AES
To generate a valid pre-authenticated login token, you need the secret given to you in your FlickRocket admin. The secret is used to derive two cryptographic keys — one for encryption and one for signing. This key derivation is done through the use of the SHA-256 hash function (the first 128 bit are used as encryption key and the last 128 bit are used as signature key).
The encryption provides confidentiality. It makes sure that no one can read the customer data. As encryption cipher, we use the AES algorithm (128 bit key length, CBC mode of operation, random initialization vector).
Step 3. Sign the encrypted data using HMAC
The signature (also called message authentication code) provides authenticity. It makes sure that the pre-authenticated login token is authentic and hasn't been tampered with. We use the HMAC algorithm with a SHA-256 hash function and we sign the encrypted JSON data from step 2 (not the plaintext JSON data from step 1).
Step 4. Base64 encode the binary data
The pre-authenticated loginlogin token now consists of the 128 bit initialization vector, a variable length ciphertext, and a 256 bit signature (in this order). This data is encoded using base64 (URL-safe variant, RFC 4648).
Step 5. Redirect your customer to your FlickRocket store
Once you have the token, you should trigger a HTTP GET request to your FlickRocket store.
GET /api/customers/login/{themesettings_id}/{login_token}
When the request is successful (e.g. the token is valid and not expired), the customer will be created under the themesettings_id and gets logged in to the FlickRocket store.
The pre-authenticated login token is only valid within a short timeframe and each token can only be used once. For those reasons, you should not generate tokens in advance for rendering them into your HTML sites. You should create a redirect URL which generates tokens on-the-fly when needed and then automatically redirects the browser.
Security considerations
We highly encourage you to always set the "remote_ip" field in the customer data hash, so that only the intended browser can use the token. We also encourage you to send tokens to the browser using secure HTTPS connections.
You should make sure that registering new accounts at your main website requires validation of the email address which is used. Otherwise, someone could sign up to your main site using somebody elses email address, thus getting access to his customer account in your FlickRocket store.
What can you do with Customer?
The FlickRocket API lets you do the following with the Customer resource. More detailed versions of these general actions may be available:
GET /api/customers.json?updated_at_min=2016-03-16%2021:03:29
Receive a list of all Customers
GET /api/customers/search.json?query=email:Bob@some.com
Search for customers matching supplied query
GET /api/customers/#{token}.json
Receive a single Customer identified via token
POST /api/customers.json
Create a new Customer
PUT /api/customers/#{token}.json
Modify an existing Customer identified via token.
DELETE /api/customers/#{token}.json
Remove a Customer identified by a token from the database
GET /api/customers/count.json
Receive a count of all Customers
GET /api/orders.json?customer_token=207119551
Find orders belonging to customer identified by his token.
Customer Properties
addresses |
"addresses": []
One or more addresses of the customer.
{"address1": "Heinrich-Hertz-Str. 2"}
{"address2": ""}
{"city": "Dortmund"}
{"company": ""}
{"country": "Germany"}
{"country_name": "Germany"}
{"country_code": "DE"}
{"default": true}
{"first_name": "John"}
{"id": 159501}
{"last_name": "doe"}
{"name": "Test"}
{"phone": "0231-12345678"}
{"province": ""}
{"province_code": ""}
{"token": "TCMJEOTSBEVTDLFU"}
{"zip": "44227"}
|
created_at |
{"created_at": "2016-04-07T16:12:24"}
GMT date and time when the customer was initially created.
|
default_address |
"default_address":
The default address of the user unless a different address was selected.
{"address1": "Heinrich-Hertz-Str. 2"}
{"address2": ""}
{"city": "Dortmund"}
{"company": ""}
{"country": "Germany"}
{"country_name": "Germany"}
{"country_code": "DE"}
{"default": true}
{"first_name": "John"}
{"id": 159501}
{"last_name": "Doe"}
{"name": "Test"}
{"phone": "0231-12345678"}
{"province": ""}
{"province_code": ""}
{"token": "TCMJEOTSBEVTDLFU"}
{"zip": "44227"}
|
email |
{"email": "someone@somewhere.com"}
The customers email address. This email address must be used by the customer to log in to the shop and players.
|
first_name |
{"first_name": "John"}
The customer's first (given) name.
|
id |
{id": 159501}
Unique ID for this customer.
|
language |
{"language": "de"}
Two byte language code.
|
last_name |
{"last_name": "Doe"}
The customer's last (family) name.
|
last_order_id |
{"last_order_id": 206897}
The last order_id of the customer.
|
last_order_name |
{"last_order_name": "#206897"}
The name of the last order.
|
note |
{"note": ""}
Notes about this customer.
|
orders_count |
{"orders_count": 3}
The number of times the cutomer has ordered.
|
password |
{"password": null}
The customer's password if customer is not identified via customer_token
|
password_confirmation |
{"password_confirmation": null}
Same as password (used for confirmation)
|
state |
{"state": "enabled"}
The ste of the order. supported values are "enabled" and "disabled". Read-only.
|
token |
{"token": "TCMJEOTSBEVTDLFU"}
The token can be used to reference this customer.
|
total_spent |
{"total_spent": 0.0}
The total amount the customer has spent.
|
updated_at |
{"updated_at": "2016-04-07T16:12:24"}
GMT date and time of the last update to the customer information
|
verified_email |
{"verified_email": false}
Is set to true when the email has been verified.
|
Receive a list of all Customers
GET /api/customers.json?updated_at_min=2016-03-16%2021:03:29
View Response
GET /api/customers.json?updated_at_min=2015-03-16T21:03:29
{
"customers": [{
"id": 147900,
"email": "01@flickrocket.com",
"password": null,
"password_confirmation": null,
"created_at": "2015-10-29T14:20:46",
"updated_at": "2015-10-29T14:20:46",
"first_name": "Test",
"last_name": "Test",
"language": "en",
"orders_count": 1,
"state": "enabled",
"total_spent": 0,
"last_order_id": 190405,
"note": "",
"verified_email": true,
"last_order_name": "#190405",
"token": "",
"default_address": {
"id": 147900,
"first_name": "Test",
"last_name": "Test",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test Test"
},
"addresses": [{
"id": 147900,
"first_name": "Test",
"last_name": "Test",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test Test"
}]
}, {
"id": 133995,
"email": "test10@flickrocket.com",
"password": null,
"password_confirmation": null,
"created_at": "2015-07-01T07:33:29",
"updated_at": "2015-07-01T07:33:29",
"first_name": "Test",
"last_name": "Sample",
"language": "de",
"orders_count": 3,
"state": "enabled",
"total_spent": 300,
"last_order_id": 172380,
"note": "",
"verified_email": true,
"last_order_name": "#172380",
"token": "",
"default_address": {
"id": 133995,
"first_name": "Test",
"last_name": "Sample",
"company": "ACE GmbH",
"address1": "Heinrich-Hertz-Str.2",
"address2": "",
"zip": "44227",
"city": "Dortmund",
"phone": "",
"language": "de",
"token": "",
"country": "Germany",
"country_name": "Germany",
"country_code": "DE",
"default": true,
"province_code": "",
"province": "",
"name": "Test Sample"
},
"addresses": [{
"id": 133995,
"first_name": "Test",
"last_name": "Sample",
"company": "ACE GmbH",
"address1": "Heinrich-Hertz-Str.2",
"address2": "",
"zip": "44227",
"city": "Dortmund",
"phone": "",
"language": "de",
"token": "",
"country": "Germany",
"country_name": "Germany",
"country_code": "DE",
"default": true,
"province_code": "",
"province": "",
"name": "Test Sample"
}]
}, {
"id": 129881,
"email": "fpackage3@mailinator.com",
"password": null,
"password_confirmation": null,
"created_at": "2015-04-29T08:39:17",
"updated_at": "2015-04-29T08:39:17",
"first_name": "",
"last_name": "",
"language": "en",
"orders_count": 1,
"state": "enabled",
"total_spent": 0,
"last_order_id": 190053,
"note": "",
"verified_email": true,
"last_order_name": "#190053",
"token": "",
"default_address": {
"id": 129881,
"first_name": "",
"last_name": "",
"company": "",
"address1": "",
"address2": "",
"zip": "",
"city": "",
"phone": "",
"language": "en",
"token": "",
"country": "United States of America",
"country_name": "United States of America",
"country_code": "US",
"default": true,
"province_code": "",
"province": "",
"name": " "
},
"addresses": [{
"id": 129881,
"first_name": "",
"last_name": "",
"company": "",
"address1": "",
"address2": "",
"zip": "",
"city": "",
"phone": "",
"language": "en",
"token": "",
"country": "United States of America",
"country_name": "United States of America",
"country_code": "US",
"default": true,
"province_code": "",
"province": "",
"name": " "
}]
}]
}
Search for customers matching supplied query
GET /api/customers/search.json?query=email:Bob@some.com
View Response
GET /api/customers/search.json?query=email:01@flickrocket.com
{
"customers": [{
"id": 147900,
"email": "01@flickrocket.com",
"password": null,
"password_confirmation": null,
"created_at": "2015-10-29T14:20:46",
"updated_at": "2015-10-29T14:20:46",
"first_name": "Test",
"last_name": "Test",
"language": "en",
"orders_count": 1,
"state": "enabled",
"total_spent": 0,
"last_order_id": 190405,
"note": "",
"verified_email": true,
"last_order_name": "#190405",
"token": "",
"default_address": {
"id": 147900,
"first_name": "Test",
"last_name": "Test",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test Test"
},
"addresses": [{
"id": 147900,
"first_name": "Test",
"last_name": "Test",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test Test"
}]
}]
}
Receive a single Customer identified via token
GET /api/customers/#{token}.json
View Response
GET /api/customers/YLQCIUSBHVCTQUVN.json
{
"customer": {
"id": 147900,
"email": "01@flickrocket.com",
"created_at": "2015-10-29T14:20:46",
"updated_at": "2015-10-29T14:20:46",
"first_name": "Test",
"last_name": "Test",
"language": "en",
"orders_count": 1,
"state": "enabled",
"total_spent": 0,
"last_order_id": 190405,
"note": "",
"verified_email": true,
"last_order_name": "#190405",
"token": "YLQCIUSBHVCTQUVN",
"default_address": {
"id": 147900,
"first_name": "Test",
"last_name": "Test",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "YLQCIUSBHVCTQUVN",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test Test"
},
"addresses": [{
"id": 147900,
"first_name": "Test",
"last_name": "Test",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "YLQCIUSBHVCTQUVN",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test Test"
}]
}
}
Create a new Customer
POST /api/customers.json
{
"customer": {
"first_name": "Steve",
"last_name": "Lastnameson",
"email": "steve.lastnameson@example.com",
"addresses": [{
"address1": "123 Oak St",
"city": "Ottawa",
"province": "ON",
"phone": "555-1212",
"zip": "123 ABC",
"last_name": "Lastnameson",
"first_name": "Mother",
"country": "CA"
}],
"password": "newpass",
"password_confirmation": "newpass"
}
}
View Response
{
"customer": {
"id": 154267,
"email": "steve.lastnameson@example.com",
"created_at": "2016-04-21T14:23:21",
"updated_at": "2016-04-21T14:23:21",
"first_name": "Mother",
"last_name": "Lastnameson",
"language": "en",
"orders_count": 0,
"state": "enabled",
"total_spent": 0,
"last_order_id": 0,
"note": "",
"verified_email": true,
"last_order_name": "#0",
"token": "DXJLLDPXRKTMVYVN",
"default_address": {
"id": 154267,
"first_name": "Mother",
"last_name": "Lastnameson",
"company": "",
"address1": "123 Oak St",
"address2": "",
"zip": "123 ABC",
"city": "Ottawa",
"phone": "555-1212",
"language": "en",
"token": "DXJLLDPXRKTMVYVN",
"country": "Canada",
"country_name": "Canada",
"country_code": "CA",
"default": true,
"province_code": "ON",
"province": "ON",
"name": "Mother Lastnameson"
},
"addresses": [{
"id": 154267,
"first_name": "Mother",
"last_name": "Lastnameson",
"company": "",
"address1": "123 Oak St",
"address2": "",
"zip": "123 ABC",
"city": "Ottawa",
"phone": "555-1212",
"language": "en",
"token": "DXJLLDPXRKTMVYVN",
"country": "Canada",
"country_name": "Canada",
"country_code": "CA",
"default": true,
"province_code": "ON",
"province": "ON",
"name": "Mother Lastnameson"
}]
}
}
Modify an existing Customer identified via token.
PUT /api/customers/#{token}.json
/api/customers/YLQCIUSBHVCTQUVN.json
{
"customer": {
"first_name": "Test_first_name",
"last_name": "Test_last_name"
}
}
View Response
{
"customer": {
"id": 147900,
"email": "01@flickrocket.com",
"created_at": "2015-10-29T14:20:46",
"updated_at": "2015-10-29T14:20:46",
"first_name": "Test_first_name",
"last_name": "Test_last_name",
"language": "en",
"orders_count": 1,
"state": "enabled",
"total_spent": 0,
"last_order_id": 190405,
"note": "",
"verified_email": true,
"last_order_name": "#190405",
"token": "YLQCIUSBHVCTQUVN",
"default_address": {
"id": 147900,
"first_name": "Test_first_name",
"last_name": "Test_last_name",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "YLQCIUSBHVCTQUVN",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test_first_name Test_last_name"
},
"addresses": [{
"id": 147900,
"first_name": "Test_first_name",
"last_name": "Test_last_name",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "YLQCIUSBHVCTQUVN",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test_first_name Test_last_name"
}]
}
}
Remove a Customer identified by a token from the database
DELETE /api/customers/#{token}.json
View Response
DELETE /api/customers/DXJLLDPXRKTMVYVN.json
{}
Receive a count of all Customers
GET /api/customers/count.json
View Response
GET /api/customers/count.json
{
"count": 20
}
Find orders belonging to customer identified by his token.
GET /api/orders.json?customer_token={token}
View Response
GET /api/orders/?customer_token=YLQCIUSBHVCTQUVN
{
"orders": [{
"id": 190405,
"email": "01@flickrocket.com",
"closed_at": "0001-01-01T00:00:00",
"created_at": "0001-01-01T00:00:00",
"updated_at": "0001-01-01T00:00:00",
"theme_setting_id": null,
"gateway": "Manual",
"test": true,
"total_weight": 0,
"taxes_included": false,
"currency": "GBP",
"financial_status": "paid",
"confirmed": true,
"buyer_accepts_marketing": true,
"name": "#190405",
"total_line_items_price": 0,
"total_price": 0,
"subtotal_price": 0,
"total_tax": 0,
"total_discounts": 0,
"referring_site": null,
"landing_site": null,
"cancelled_at": null,
"checkout_token": "7b20615d-6012-483f-ad28-c8be6aeb8ce1",
"location_id": null,
"source_identifier": null,
"processed_at": "0001-01-01T00:00:00",
"device_id": null,
"browser_ip": "87.156.135.181",
"landing_site_ref": null,
"order_number": "",
"discount_codes": [],
"payment_gateway_names": ["Manual"],
"source": "",
"checkout_id": 104788,
"source_name": "webshop",
"fulfillment_status": null,
"tax_lines": [],
"line_items": [{
"id": 379582,
"product_id": "0000-D575-EF10-F7E2",
"license_id": 17,
"hd": true,
"title": "German ExE",
"license_title": "Download to own (permanent access)",
"quantity": 1,
"grams": 0,
"sku": "",
"price": 0,
"taxable": false,
"requires_shipping": false,
"gift_card": false,
"name": "German ExE / Download to own (permanent access)",
"product_exists": true,
"total_discount": 0
}],
"shipping_lines": [],
"fulfillments": [],
"refunds": [],
"customer": {
"id": 147900,
"email": "01@flickrocket.com",
"created_at": "2015-10-29T14:20:46",
"updated_at": "2015-10-29T14:20:46",
"first_name": "Test_first_name",
"last_name": "Test_last_name",
"language": "en",
"orders_count": 1,
"state": "enabled",
"total_spent": 0,
"last_order_id": 190405,
"note": "",
"verified_email": true,
"last_order_name": "#190405",
"token": "YLQCIUSBHVCTQUVN",
"default_address": {
"id": 147900,
"first_name": "Test_first_name",
"last_name": "Test_last_name",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "YLQCIUSBHVCTQUVN",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test_first_name Test_last_name"
},
"addresses": [{
"id": 147900,
"first_name": "Test_first_name",
"last_name": "Test_last_name",
"company": "Sample Company",
"address1": "Markgrafenstr 92",
"address2": "",
"zip": "44139",
"city": "Dortmund",
"phone": "+49 231 976765 0",
"language": "en",
"token": "YLQCIUSBHVCTQUVN",
"country": "United Kingdom",
"country_name": "United Kingdom",
"country_code": "GB",
"default": true,
"province_code": "IL",
"province": "IL",
"name": "Test_first_name Test_last_name"
}]
},
"shipping_address": null
}]
}