Introduction
The CardSavr REST API is a service for managing payment card circulation on merchant websites. It uses REST principles and standard HTTP features, such as HTTP verbs, as well as several layers of security to protect sensitive data.
CardSavr responses and requests support JSON-formatted bodies only.
Authentication
To authorize, an init or login call (differs per SDK) is required:
const { CardsavrHelper } = require("@strivve/strivve-sdk/lib/cardsavr/CardsavrJSLibrary-2.0");
const session = new CardsavrSession(cardsavr_server, app_key, app_name);
const login_data = await session.init(username, password);
//await session.getCards({}); //session can now be used to make api calls
using Switch.CardSavr.Http;
CardSavrHttpClient session = new CardSavrHttpClient(_cardsavrServer,
_appKey, _appName, userName, password);
CardSavrResponse<LoginResult> login = await session.Init();
//await session.getCardsAsync(); //session can now be used to make api calls
import com.strivve.CardsavrSession;
this.session = CardsavrSession.createSession(integratorName, integratorKey, apiServer);
JsonObject obj = (JsonObject) session.login(username, password, null);
# With a shell, you must first establish a session, followed by
# a login command. Keep in mind, this ONLY works
# with a development server that supports unsigned body requests.
curl "https://api.INSTANCE.cardsavr.io/session/start"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}"
curl -iv -d "{\"password\": \"PASSWORD\", \"userName\": \"USERNAME\"}"
-H "Content-Type: application/json" "https://api.INSTANCE.cardsavr.io/session/login"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}"
The SDK calls hide the implementation of the login. Login includes an ECDH key exchange, password signing, and the establishment of a session secret key, which will be used for all future encryptions. It also leverages a session token which enables the client to access their session on the server.
{
"server_public_key": "sample_public_key",
"session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4ZjJkYjQ1OS1kODMzLTQ2NmItOGE0MS1mYzcwMzA1M2QwZGIiLCJpc3MiOiJhcGkuZ3RvbWxpbnNvbi5jYXJkc2F2ci5pbyIsImF1ZCI6ImFwaS5ndG9tbGluc29uLmNhcmRzYXZyLmlvIiwiaWF0IjoxNTk5NzY5NDQ2fQ.slI13GGNot8SU_hPdzXzZrjcv90G43etofgh9HotNj0",
"user_id": 321,
"user":
{
"id": 123,
"username": "john_smith_123",
"first_name": "John",
"last_name": "Smith",
"email": "jsmith@email.com",
"is_locked": true,
"role": "dev",
"created_on": "2018-04-19T23:10:36.657Z",
"last_updated_on": null
}
}
There is more information in the session endpoint documentation. If you decide not to use one of the Strivve SDKs, you are responsible for encryption of all bodies passed into the REST API.
Headers
There is a set of required and optional headers. The SDKs abstract most of these settings, but it's important to understand how they are used when making REST calls.
REST calls support and/or require the following headers once the session is established.
Header | Default | Type | Description |
---|---|---|---|
x-cardsavr-trace | required | stringified JSON object | See trace |
x-cardsavr-client-application | integrator name | string | unique per application, integrator name provided as default when using an SDK |
x-cardsavr-authorization | required | string | contains the integrator name and a prefix, populated by SDK libraries. |
x-cardsavr-nonce | required | string (milliseconds) | contains the current UTC time in milliseconds, and therefore provides protection against replay attacks. |
x-cardsavr-signature | required | string | The string-to-sign format requires the URL-Path (decoded), the authorization header, and the nonce header. Also part of the SDK Libraries. |
x-cardsavr-hydration | (none) | stringified JSON object | See hydration |
x-cardsavr-paging | {"page": 1, "page_length": 25, "is_descending" : true} | stringified JSON object | Only supported with GET calls. See paging |
x-cardsavr-session-jwt | required | string | See session tokens |
session-tokens
CardSavr needs to maintain an API session for state management including authentication, session key, replay prevention, etc. Standard RFC-7519 JWT tokens are used for client sessions. The x-cardsavr-session-jwt header is used with token based sessions. The x-cardsavr-session-jwt header is managed transparently within the Strivve SDK. It is the responsibility of applications directly using the direct REST protocol to set this header for each request.
With POST /session/login to begin a new session, this header is not required and will be ignored.
With all subsequent requests on a session
"x-cardsavr-session-jwt": value-returned-from-session-login
Trace
Setting a sample trace header
//initialize as part of the session initialization; if not set
//explicitly, the trace header defaults to the unique username of //the client user. If an agent user is operating on behalf of a
//cardholder, the cardholder cid is the default. The example //specifies how to change it.
await session.init(username, password, JSON.stringify({key: "NlOFNNlKabi7Fn26CLw="}));
session.setTrace("NlOFNNlKabi7Fn26CLw=");
//or per request
await session.getUsers({}, {}, {"x-cardsavr-trace": JSON.stringify({key: "NlOFNNlKabi7Fn26CLw="})});
//Add a trace at the start of the session
CardSavrHttpClient session = new CardSavrHttpClient(_cardsavrServer,
_appKey, _appName, userName, password, null, "{\"key\": \"my_trace\"}");
//or per request
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
headers.Add("x-cardsavr-trace", "{\"key\": \"my_trace\"}");
CardSavrResponse<List<User>> result = await http.GetUsersAsync(null, null, headers);
CardsavrSession session = CardsavrSession.createSession(integratorName, integratorKey, apiServer);
//Add a trace at the start of the session
JsonObject trace = createObjectBuilder().add("key", "my_trace").build();
(JsonObject) session.login(username, password, trace);
//or per request
Headers headers = session.createHeaders();
headers.trace = trace;
session.post("/cardsavr_cards", body, headers);
curl "https://api.INSTANCE.cardsavr.io/cardsavr_users"
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\", \"bid\": \"hEOF26sbi7FCNNlLw==\"}"
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
"x-cardsavr-trace": JSON-stringified trace object
CardSavr uses trace headers to trace all request-related activity within the CardSavr infrastructure. When a request is made to CardSavr, any ID included in the trace header will appear in all logging associated with that request. This allows for quick troubleshooting and monitoring. .
The trace header takes a JSON-stringified object, which can be as simple or as complex as necessary for the given application. The trace is a required header, and must contain at least a trace "key". Within the SDKs, the trace key defaults to the username of the session.
Type | Description | Example |
---|---|---|
key | unique key that identifies a request or set of requests | `trace: '{ "key": "hEOFNKapn26sbi7FCNNlLw==" }' |
A trace header can contain multiple trace IDs. It is up to the developer to mint trace IDs in a way that best categorizes their app's requests. If a backend server is used, adding the trace IDs into the backend server logs can yield additional tracing efficacy.
Hydration
Setting a sample Hydration Header
await session.getCards(123, {}, { "x-cardsavr-hydration": JSON.stringify(["address"]) });
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
headers.Add("x-cardsavr-hydration", "[\"address\"]");
CardSavrResponse<List<Card>> result = await
http.GetCardsAsync(123);
CardsavrSession header = session.createHeaders();
headers.hydration = Json.createArrayBuilder().add("address").build();
session.get("/cardsavr_cards", 1, headers);
curl "https://api.INSTANCE.cardsavr.io/cardsavr_cards/123"
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\"}"
-H "x-cardsavr-hydration: [\"address\"]"
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
{
"id": 123,
"cardholder_id": 3,
"bin_id": 5,
"address_id": 7,
"par": "Q1J4AwSWD4Dx6q1DTo0MB21XDAV76",
"expiration_month": "03",
"expiration_year": "20",
"name_on_card": "Joe Smith",
"first_name": "Joe",
"last_name": "Smith",
"created_on": "2019-02-06T20:33:23.094Z",
"last_updated_on": "2019-03-13T22:32:30.897Z",
"address":
{ "cardholder_id": 3,
"is_primary": false,
"address1": "12345 Harris Ave",
"address2": "STE. 601",
"city": "Seattle",
"subnational": "WA",
"country": "USA",
"postal_code": "98133",
"postal_other": 98133-1234,
"created_on": "2019-02-02T10:12:51.081Z",
"last_updated_on": "2019-02-06T20:33:23.094Z"
}
}
{"x-cardsavr-hydration": {JSON-stringified array of resources to be hydrated}}
For requests against a resource type that contains foreign key references (e.g. 'address_id' for 'cardsavr_cards'), a hydration header will "hydrate" (i.e. fill out) any of the resources indicated. Therefore, any objects returned in the response body will contain additional key-value pairs for each of the resources listed, where the key is the resource name (e.g. "address" in the previous example) and the value is the full object.
For example, including the header {hydration: '["address"]'} in a successful PUT request to '/cardsavr_cards/123' would return the updated card with an additional 'address' property containing the full address object associated with that card.
Nested hydration can also be used. For example, the following header:
{"x-cardsavr-hydration": '["card.cardholder"]'}
for the endpoint '/place_card_on_multiple_sites_jobs' would hydrate the associated card AND cardholder (i.e. user) associated with the card. Hydration headers can be used with any endpoint for any resource that contains foreign key references.
Financial Institution
A financial-institution header is required on many calls that require FI specfic context. For example, all cardholders must belong to a financial insitution, and thus the header is required upon creation. The header is preferred over applying to the body to avoid the unnecessary extra lookup call. The SDK functions that require the fi have a required parameter in the corresponding function.
Client Application
Setting a custom application header (defaults to app name)
session.setSessionHeaders( {'client-application': 'my-client-app' });
http.SetIdentificationHeader('my-client-app');
//Not implemented, must pass as a header
curl "https://api.INSTANCE.cardsavr.io/cardsavr_cards/123"
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\"}"
-H "client-application: \"my-client-app\""
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
{'client-application': {client application name}}
Your client application name will appear in the CardSavr logs alongside each request and response for your app, making troubleshooting and any other information retrieval much easier. Choose a name that clearly identifies your specific app for improved log searching (e.g. "acmebank-web-app"). When using the SDKs, the client-application defaults to the integrator name, and this is generally acceptable for most use cases. This is an optional header, but recommended when not using the SDK.
Paging
Paging headers give you the flexibility to modify the number of results returned, and how they should be sorted.
//javascript SDK supports a json object as a paging header
await session.getCards(123, {"sort":"id","is_descending":true,"page":1,"page_length":25});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = “id” };
CardSavrResponse<List<Card>> list = await http.getCardsAsync(null, paging);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
session.post("/cardsavr_cards", body, headers);
curl "https://api.INSTANCE.cardsavr.io/cardsavr_cards/123"
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\"}"
-H "x-cardsavr-paging: \"{\"page\": \"1\"}\""
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
{'paging': 'JSON-stringified paging object'}
CardSavr uses paging headers in both requests to and responses from batch GET endpoints. When sent with a batch GET request, a paging header specifies the length, sorting criterion, page number, and order of the data returned. Since each batch GET request can only return one page of data at a time, paging headers give users more control over the data they receive back.
If no paging header is submitted with the request, default values are applied (see table).
Note: CardSavr sends a paging header with each batch GET response to provide details about the page returned.
In the example header at right sent to '/cardsavr_cards', the second page of 25 results would be returned, sorted in descending order by PAR.
Parameters
The paging header takes a JSON stringified object with the following properties. If a paging header is not included, the page of results will use the default values. Results are returned as an array.
Property name | Type | Description | Default value |
---|---|---|---|
page | integer | The page to be returned | 1 |
page_length | integer | Length of each page | 25 |
sort* | string | Property to sort results by | "id" |
descending | boolean | If true, sorts results in descending order; if false, sorts in ascending order | false |
*Check GET endpoint documentation to see which properties are sort-able
Safe key
Safe keys are required to encrypt PII data (email address, address, name) and PCI data (PAN, CVV) Customers are encouraged to store their own safe keys outside the cardsavr environment. This prevents the API from examining sensitive data. If safe key storage is deemed unnecessary (espeically for short lived cardholders), Strivve has the ability to store the safe key on behalf of the customer. By omitting the safe key when adding cardholders, Strive will generate a safe key and store it along with the cardholder, so there is no need to send a safe key header. It is strongly encouraged not to use a Strivve managed safe key if cardholders are going to persist for long periods of time.
Although safe keys are stored with the cardholder, callers cannot persist a safe key on the body of the cardholder.
const body = { email : "foo@foo.com", cuid : "samplecuid"};
const res = await my_session.createCardholder(body, cardholder_safe_key);
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
AddSafeKeyHeader(headers, safeKey);
PropertyBag bag = new PropertyBag();
bag["id"] = 1;
bag["email"] = "foo@foo.com";
await http.UpdateUserAsync(bag.GetString("id"), bag, null, headers); //no paging
Headers headers = session.createHeaders();
headers.safeKey = SAFE_KEY;
headers.newSafeKey = NEW_SAFE_KEY;
JsonObject obj = Json.createJsonBuilder().add("id", 1).build();
JsonObject response = session.update("/cardsavr_users", obj, headers);
curl "https://api.INSTANCE.cardsavr.io/cardsavr_users/1"
-X PUT
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\"}"
-H "x-cardsavr-new-cardholder-safe-key: +h+W0c9EsgvFLufWnu87iV6ErDF7dpyT5YUEbb/oOIw=}"
-H "x-cardsavr-cardholder-safe-key: rttYqkGPHLk2KeK6OD8612gSurKXu0X8W6BTWF3hhGM=}"
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
-B "{ \"id\": 1, \"cardholder_safe_key\": \"+h+W0c9EsgvFLufWnu87iV6ErDF7dpyT5YUEbb/oOIw=\" }"
{'cardholder-safe-key': 'rttYqkGPHLk2KeK6OD8612gSurKXu0X8W6BTWF3hhGM='}
{'new-cardholder-safe-key': '+h+W0c9EsgvFLufWnu87iV6ErDF7dpyT5YUEbb/oOIw='}
You must send an encrypted cardholder safe key header for each request that involves safe-protected information. Saving users (/cardsavr_users), accounts (/cardsavr_accounts) and cards (/cardsavr_cards) requires the key in order to write encrypted data like PANs and merchant site passwords to the server side safe. Safe keys can be stored by the third party, or they can optionally be stored by Strivve within Cardsavr. Individual endpoint documentation will indicate if a safe key header is required.
When rotating a safe key, you must provide a 'new-cardholder-safe-key' header. Both headers are required (new- and existing) in this case.
See the cardholder safe key section for more information on generating and using safe keys.
API Usage
Query parameter filters can be used with GET requests that do not have an ID path parameter (i.e. '/cardsavr_cards' but not '/cardsavr_cards/123'). When using a query filter, you must place a '?' after the endpoint (preceding the first query filter). Mutiple query filters must be separated by an '&'. There are six filter types in CardSavr:
GET Filters
Filters can be aggregated together to apply multiple filters
const merchants = await session.getMerchantSites({ top_hosts : "amazon.com,apple.com", exclude_hosts : "walmart.com" });
CardSavrResponse<List<MerchantSite>> merchants = await http.GetMerchantSitesAsync(
new NameValueCollection() {
{ "top_hosts", "amazon.com,apple.com"}, {"exclude_hosts", "walmart.com" }
}
);
List<NameValuePair> filters = new ArrayList<>(1);
filters.add(new BasicNameValuePair("tags", "canada"));
JsonArray response = (JsonArray)session.get("/merchant_sites", filters, null);
curl "https://api.INSTANCE.cardsavr.io/cardsavr_users?top_hosts=amazon.com,apple.com&exclude_hosts=walmart.com"
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\"}"
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
Singular filters
Singular filters select for results with one specific value. If the property has a unique constraint (e.g. "username" for '/cardsavr_users'), the singular filter can only select one object.
For string properties, singular filters always use partial matching, meaning they will match any string that contains the filter value as a substring.
Multiple filters
Multiple filters select for any object containing one of the specified values for a property. Multiple values must be separated by commas and no spaces. A single value can be submitted for multiple filter, as well.
Multiple filters for string properties always use partial matching, meaning they will match any string that contains the filter value as a substring.
Starts-with filters
Starts-with filters select all objects where the property value begins with the provided query value.
Top filters
Top filters select for objects with specified properties to be returned first, in the order specified.
Include/exclude filters
Include filters select for any objects that have the specified property value. Unlike multiple filters, include filters use exact matching.
Exclude filters select for any objects that do NOT have the specified property value. Exclude filters use exact matching.
Min/Max filters
Max filters select for objects that have a value equal to or less than the specified value.
Min filters select for any objects that have a value equal to or greater than the specified value.
Cascading DELETE
Deleting user 123 will delete their corresponding jobs, cards, and addresses. Their job results will remain.
await session.deleteCardholder(123);
await http.DeleteCardholderAsync(123);
session.delete("/cardholder", 123);
curl "https://api.INSTANCE.cardsavr.io/cardsavr_users"
-X DELETE
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\"}"
-B "{ \"id\": 123 }"
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
A successful DELETE request will also delete any object that references the deleted object. The additional object types that will be deleted for a particular DELETE endpoint are listed in the individual endpoint documentation.
For example, a successful DELETE request to '/cardsavr_accounts/123' would also delete any single-site jobs that reference the account with ID 123, as single-site jobs contain a foreign key reference to an account.
Plural POST
await session.createSingleSiteJobs([{"cardholder_id": 1, "account_id": 1, "status" : "REQUESTED"},
{"cardholder_id": 2, "account_id": 2, "status" : "REQUESTED"}]);
//unsupported
JsonArray body = Json.createArrayBuilder()
.add(Json.createJsonBuilder().add("cardholder_id", 1).add("account_id", 1).add("status", "REQUESTED").build())
.add(Json.createJsonBuilder().add("cardholder_id", 1).add("account_id", 2).add("status", "REQUESTED").build())
.build();
await session.post("/place_card_on_single_site_jobs", body, null);
curl "https://api.INSTANCE.cardsavr.io/place_card_on_single_site-jobs"
-X POST
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\"}"
-B "{\"cardholder_id\": 1, \"account_id\": 1, \"status\" : \"REQUESTED\"}, {\"cardholder_id\": 1, \"account_id\": 2, \"status\" : \"REQUESTED\"}]"
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
Some objects support bulk creation (e.g. single site jobs). This is accomplished by passing in array of objects rather than simply a single object.
Plural PUT/DELETE
Some objects support updating and deleting using the standard filter parameters (e.g. single site jobs). This is noted in the per-object documentation.
Customer keys and Upserting
Cards, cardholders, and accounts support external references. This enables integrators to access entities using alternative namespaces rather than by the cardsavr supplied ids. These external references are generally existing entities in the integrators system (e.g. a cardholder bank account id).
Integrators can also "upsert" these entities by providing the customer_key rather than cardsavr ids. If the entity exists, it is merely updated and returned. If the entity does not exist, it will be created. This simplifies the integration and can reduce the complexity of the integrator's middleware.
Entity | External ID | Default | card_placement_result column |
---|---|---|---|
Cardholder | cuid | random | cuid |
Card | customer_key | random | card_customer_key |
Account | customer_key | merchant site, $, and cuid concatenated | account_customer_key |
Request Hydration on POST
await session.createSingleSiteJob(body);
//unsupported
JsonObject body = Json.createObjectBuilder()
.add(... //various nested properties using JsonObjects and JsonArrays (JsonValues)
.build();
await session.post("/place_card_on_single_site_jobs", body, null);
curl "https://api.INSTANCE.cardsavr.io/place_card_on_single_site-jobs"
-X POST
-H "x-cardsavr-trace: {\"key\": \"NlOFNNlKabi7Fn26CLw==\"}"
-B "{\"cardholder_id\": 1, \"account_id\": 1, \"status\" : \"REQUESTED\"}, {\"cardholder_id\": 1, \"account_id\": 2, \"status\" : \"REQUESTED\"}]"
-H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
{
"status": "REQUESTED",
"cardholder":
{
"cuid":"12345678",
},
"card":
{
"cardholder_ref": {
"cuid": "12345678"
},
"customer_key":"12345678",
"par":"peLpzDnEHdhiiWEtuhUgIbN12345678",
"pan":"KOnalFfwdrBXlZD",
"cvv":"123",
"expiration_month":12,
"expiration_year":24,
"name_on_card":"FirstName LastName",
"address":
{
"cardholder_ref": {
"cuid": "12345678"
},
"first_name":"Switch",
"last_name":"Strivve",
"address1":"SGTClNSCCMqlfjuzTmJuepDyFgvWhlCMRycXlKGiRIooOJJkoXeObOcAwJMGeqjSDWfhTHobAWMimcCynMIQcvlBFSbMQlwUFyJ",
"address2":"AyFgoCTjCLXUQVylBAfkHJOtqkkKJjuaLHnmJpSctqBOQueIvciyAUPqYoFpkiAPlkGjgPuabhAPCHFPvaxciObOmIBvBUWpngD",
"city":"Seattle",
"subnational":"WA",
"postal_code":"98177",
"email":"email@domain.com",
"phone_number":"5555555555",
"country":"USA",
"is_primary": true
}
},
"account":
{
"cardholder_ref": {
"cuid": "12345678"
},
"merchant_site_id":1,
"username":"bad_email",
"password":"good_password"
}
}
Some objects support posting multiple nested objects to avoid multiple server calls. This is supported by the Single Site Job, Card, Account and Address APIs. For example, a Job can be posted with a nested cardholder, account, and a card (the card can even have a nested address). This is currently only supported when single jobs are posted, not with Plural POSTs.
If a nested cardholder is referenced by multiple objects, the nested object should reference the created instance using the cardholder cuid. Notice the body required on the request to the right. A cardholder_ref parameter is required on card, account, and address entities to ensure the correstponding cardholder_id properties are filled in properly.
Passwords and Authorization
Authorize cardholder
Credential grants are very important for handing off responbility to a downstream client. The grants must be provisioned by a user that can create grants (like a customer_agent), and the grant is one-time-use for 3 minutes. Grants are created when cardholders are created, and can be used as part of the authorize endpoint within the client by an agent (generally a cardholder_agent).
const { CardsavrSession } = require() "@strivve/strivve-sdk/lib/cardsavr/CardsavrJSLibrary-2.0";
//agent_session is the session of a cardholder agent. Cardholder agents are lower
//privileged agents that can authorize themselves using grants created upstream when cardholder are created.
const login = await agent_session.authorizeCardholder(grant);
const response = agent_session.createSingleSiteJob(job); //agent can now act on behalf of cardholder
using Switch.CardSavr.Http;
CardSavrResponse<UserLogin> login = await agentSession.client.authorizeCardholder(grant);
//user can now act on behalf of cardholder
import com.strivve.CardsavrSession
JsonObject login = agentSession.put("/cardholder/authorize", Json.createObjectBuilder().add("grant", grant).build(), null, null);
//user can now act on behalf of cardholder
#session must first be started, and must have permissions to create grants
curl -iv
-H "Content-Type: application/json" "https://api.INSTANCE.cardsavr.io/cardholder/{{GRANT}}/authorize"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
Grants are always 38 characters, are one time use, and expire after 3 minutes.
{
"user_credential_grant": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9ey"
}
Path
GET /cardsavr_users/:id/credential_grant
Description
Returns a credential grant for specified user. This grant can be included with an authorize endpoint call ONCE within three minutes of being created. Grants can also be hydrated into a cardholder response. Frequently grants are issued immediately following the creation of a cardholder, so this is a common workflow.
Update user password
Password updates for non-agents must supply the old_password
const { CardsavrSession } = require() "@strivve/strivve-sdk/lib/cardsavr/CardsavrJSLibrary-2.0";
await session.updatePassword(user_id, { password : new_password, password_copy : new_password});
using Switch.CardSavr.Http;
PropertyBag bag = new PropertyBag();
bag["old_password"] = old_password;
bag["password"] = new_password;
bag["password_copy"] = new_password;
CardSavrResponse<PropertyBag> result = await http.UpdateUserPasswordAsync(user_id, bag);
JsonObject body = Json.createObjectBuilder()
.add("old_password", old_password)
.add("password", password)
.add("password_copy", password_copy)
.build();
String url = String.format("/users/%d/update_password", userId);
JsonObject response = (JsonObject) session.put(url, body, null, null);
#old_pass is not required for privileged admins. Users must provide their old password
curl -iv -d "{\"password\": \"3ysXPhntmPDU7xUFYKbc/4Aq=WVrhExdjHQsx5FgV2pZ\",
\"password_copy\": \"3ysXPhntmPDU7xUFYKbc/4Aq=WVrhExdjHQsx5FgV2pZ\"}"
-H "Content-Type: application/json" "https://api.INSTANCE.cardsavr.io/cardsavr_users/:id/credential_grant"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
{
"success": true
}
Path
PUT /cardsavr_users/:id/update_password
Description
Updates CardSavr user password key. Partners are responsible for rotating their agent role password keys every 90 days. Cardholder roles cannot have passwords and must log in using credential grants.
Body parameters
Parameter | Type | Required | Desription |
---|---|---|---|
password | string | yes | New password key |
password_copy | string | yes | Copy of new password key |
old_password | string | not always | Privileged accounts can reset users' passwords without the old key |
Session
Session endpoints are used for session login, and termination.
User login
To create a new session and authorize a login call is required:
const { CardsavrSession } = require() "@strivve/strivve-sdk/lib/cardsavr/CardsavrJSLibrary-2.0";
const session = new CardsavrSession(cardsavr_server,
app_key, app_name, username, password);
const login_data = await session.init();
using Switch.CardSavr.Http;
CardSavrHttpClient session = new CardSavrHttpClient(_cardsavrServer,
_appKey, _appName, userName, password);
CardSavrResponse<LoginResult> login = await session.Init();
import com.strivve.CardsavrSession;
this.session = CardsavrSession.createSession(integratorName, integratorKey, apiServer);
JsonObject obj = (JsonObject) session.login(username, password, null);
//throws CardsavrRESTException
curl -iv -d "{\"password\": \"PASSWORD\", \"userName\": \"USERNAME\"}"
-H "Content-Type: application/json" "https://api.INSTANCE.cardsavr.io/session/login"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
The login call both starts and authorizes a new session and returns the user, along with a public key to be used in generating a new API Session Key to sign and encrypt future requests on the session. See API Session Keys for information on using Server's public key. Return a session token to be used with all subsequent calls on the session. This value is sent with the "x-cardsavr-session-jwt" header. If you are debugging with cURL or Postman, cookies are used in lieu of session tokens.
{
"server_public_key": "sample_public_key",
"session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4ZjJkYjQ1OS1kODMzLTQ2NmItOGE0MS1mYzcwMzA1M2QwZGIiLCJpc3MiOiJhcGkuZ3RvbWxpbnNvbi5jYXJkc2F2ci5pbyIsImF1ZCI6ImFwaS5ndG9tbGluc29uLmNhcmRzYXZyLmlvIiwiaWF0IjoxNTk5NzY5NDQ2fQ.slI13GGNot8SU_hPdzXzZrjcv90G43etofgh9HotNj0",
"user_id": 123,
"user":
{
"id": 123,
"username": "john_smith_123",
"first_name": "John",
"last_name": "Smith",
"email": "jsmith@email.com",
"is_locked": true,
"role": "dev",
"created_on": "2018-04-19T23:10:36.657Z",
"last_updated_on": null,
"financial_institution": {
"id": 1,
"name": "Acme Credit Union",
"description": "Users in this FI can view and perform actions on users in all other FIs.",
"lookup_key": "acmecu",
"alternate_lookup_key": null,
"config": null,
"last_activity": null,
"created_on": "2023-09-07T18:49:54.859Z",
"last_updated_on": null
}
}
}
Path
POST /session/login
Description
Login user into a CardSavr session
Body parameters
Parameter | Type | Required | Desription |
---|---|---|---|
client_public_key | string | yes | The base 64 encoded NIST point 256 (P256) elliptic curve public key from the key pair generated by the calling application. See Curve Private Key |
username | string | yes | user name for this user |
password_proof | string | no | The base 64 encoded HMAC-256 signature zero-knowledge-proof of the password. See [zero-knowedge-proof] for more information. This parameter is mutually exclusive of the 'password' and 'userCredentialGrant' parameters. |
password | string | no | User's plain text password when using Postman or Curl on a development environment. This parameter is mutually exclusive of the 'passwordProof' and 'userCredentialGrant' parameters. |
Zero Knowledge Proof Password
The CardSavr service uses a zero-knowledge-proof mechanism with passwords during login. The proof is done by producing a key derivation from the username/password and producing a HMAC-256 signature that can be verified by the CardSavr server. This is done to prevent the server from ever knowing the password. See zero knowledge proof for more information.
End session
const { CardsavrSession } = require() "@strivve/strivve-sdk/lib/cardsavr/CardsavrJSLibrary-2.0";
await session.end();
//or if using the CardsavrHelper, the cache must be cleaned up
//await helper.endSession(username);
using Switch.CardSavr.Http;
await client.EndAsync();
//or if using CardSavrHelper, you need to release the session from the cache
//await helper.CloseSession(userName);
import com.strivve.CardsavrSession;
JsonObject response = session.end();
#session must first be started
curl -iv -d -H "Content-Type: application/json" "https://api.INSTANCE.cardsavr.io/session/end"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
Session end returns a 200 with no body
Path
GET /session/end/
Description
Ends the current user session.
Accounts
Account objects contain the account information, such as username and password, for a particular cardhoder. They are used to log in to a cardholder's account for placing a payment card.
Get account
const accounts = await session.getAccounts(266084664,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["cardholder","merchant_site","cardsavr_card"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<Accounts> accounts = await session.GetAccountsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["cardholder","merchant_site","cardsavr_card"])}
JsonArray response = (JsonArray)session.get(266084664, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 266084664,
"last_password_update": "2002-03-18T08:08:08.234Z",
"last_saved_card": "1999-05-26T17:59:13.323Z",
"created_on": "1982-05-15T23:17:19.320Z",
"last_updated_on": "2020-04-02T02:59:11.166Z",
"cardholder": {
"id": 1256512418,
"type": "persistent_nocreds",
"first_name": "Jane",
"last_name": "Smith",
"email": "test_email@strivve.com",
"meta_key": "wNHNeY",
"webhook_url": "https://mywebhooks.com/this",
"custom_data": {
"CljkumxDCBge": "v1nc",
"FYNGVlCgSbYg": 4,
"TNjDyLfUugUU": false
},
"created_on": "2008-08-27T17:55:46.845Z",
"last_updated_on": "1993-02-08T13:59:02.783Z",
"cuid": "ZQcVzxSJjkIdr"
},
"merchant_site": {
"id": 1059870448,
"name": "Amazon",
"note": "riwZKUExvTEZtpiOPJGXGKbhT",
"host": "amazon.com",
"tags": [
"UU6[yYiwfvE-{3x8-p~[BdJsMtb%2GQ",
13,
"WS8B-lX~}^,vVDIara[=hujhn2r0lA"
],
"interface_type": "vbs",
"job_type": "CARD_PLACEMENT",
"required_form_fields": [
"email",
"phone_number",
"card_data",
"cvv",
"billing_address",
"postal_code"
],
"images": [
{
"url": "https://d1t7g1oas7m24a.cloudfront.net/tiles/dollarshaveclub.com?width=128&version=21f917315911eec1b1705bc7784ce861579cff2b",
"width": 128,
"grayscale": false
},
{
"url": "https://d1t7g1oas7m24a.cloudfront.net/tiles/dollarshaveclub.com?width=32&version=21f917315911eec1b1705bc7784ce861579cff2b",
"width": 32,
"grayscale": false
}
],
"account_link": [
{
"key_name": "username",
"label": "Username",
"type": "initial_account_link"
},
{
"key_name": "password",
"label": "Password",
"type": "initial_account_link",
"secret": true
},
{
"key_name": "otp",
"label": "One Time Passcode",
"type": ""
}
],
"messages": {
"mfa_label": "Additional information required, this code may be sent to your phone or email address.",
"additional_info_message": "",
"auth_message": "Linking account."
},
"script_directory": "zjQKIBnOZPKidtEIqpUS",
"record_final_site_artifacts": true,
"puppeteer_screenshot": true,
"login_page": "https://www.merchantsite.com/login",
"forgot_password_page": "https://www.merchantsite.com/forgot_password",
"credit_card_page": "https://www.merchantsite.com/credit_card",
"wallet_page": "L",
"merchant_sso_group": "TyWGYRtyN",
"tier": 1524940817,
"cookie_caching_scheme": "pre-authentication",
"dynamic_viewport": true,
"use_puppeteer": false
},
"cardsavr_card": {
"id": 459823259,
"type": "Mastercard",
"expiration_month": 12,
"expiration_year": 24,
"name_on_card": "Jane Smith",
"nickname": "Jane's VISA",
"custom_data": {
"ZccbMTevREtD": "P^nY3OZx0e(*u",
"fEUOVhnMECfl": 59,
"dWllTukvaCqM": true
},
"created_on": "2014-07-31T06:25:55.099Z",
"last_updated_on": "2018-01-06T15:13:44.537Z",
"par": "VMDEyxNytZlYmPCcHQGvpvxodytqN",
"customer_key": "xAXHoEnnCyGXassGJfiXqY"
},
"customer_key": "gCguiOAUaUKbXqX"
}
Path
GET /cardsavr_accounts (batch) or GET /cardsavr_accounts/:id (singular)
Description
Returns the account specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable accounts, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- cardholder_ids
- merchant_site_ids
- customer_key
- last_card_placed_ids
- last_password_update_min / last_password_update_max
- last_saved_card_min / last_saved_card_max
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/cardsavr_accounts?ids=1,2
Singular GET requests
Singular requests only return the account matching the id provided in the path.
Example GET request path:/cardsavr_accounts/266084664
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this account. |
last_card_placed_id | number (fk) cards | ID of the last card placed on this account by the Virtual Browser System (VBS). |
last_password_update | date | |
last_saved_card | date | Date of last card saved on this account. |
created_on | date | Date this site was created on |
last_updated_on | date | Date this site was last updated on |
cardholder_id | number (fk) cardholders | ID of the cardholder associated with this account. |
merchant_site_id | number (fk) merchant sites | ID of the merchant site associated with this account. |
customer_key | string | An external reference to a merchant site for a specific cardholder. A key of merchant host and cuid will be used if none provided. The default can potentially violate a constraint with two accounts of the same merchant site. |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create account
const account = await session.createAccount({
"cardholder_id": 908894426,
"merchant_site_id": 1248830464,
"customer_key": "gCguiOAUaUKbXqX",
"last_card_placed_id": 1263765051,
"account_link": {
"username": "jsmith123",
"password": "BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI="
}
}, CARDHOLDER_SAFE_KEY);
PropertyBag body = new PropertyBag()
{
{ "cardholder_id", 908894426 },
{ "merchant_site_id", 1248830464 },
{ "customer_key", "gCguiOAUaUKbXqX" },
{ "last_card_placed_id", 1263765051 }
};
CardSavrResponse<Account> account = await http.CreateAccountAsync(body, CARDHOLDER_SAFE_KEY);
JsonObject body = Json.createObjectBuilder()
.add("cardholder_id", 908894426 )
.add("merchant_site_id", 1248830464 )
.add("customer_key", "gCguiOAUaUKbXqX" )
.add("last_card_placed_id", 1263765051 )
.build();
JsonValue account = session.post("/cardsavr_accounts", body, null, null);
curl -d "{\"cardholder_id\":908894426,\"merchant_site_id\":1248830464,\"customer_key\":\"gCguiOAUaUKbXqX\",\"last_card_placed_id\":1263765051,\"account_link\":{\"username\":\"jsmith123\",\"password\":\"BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=\"}}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-cardholder-safe-key: CARDHOLDER_SAFE_KEY"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_accounts/
Path
POST /cardsavr_accounts
Description
Create a account and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
cardholder_id | number | yes | ID of the cardholder associated with this account. |
merchant_site_id | number | yes | ID of the merchant site associated with this account. |
customer_key | string | yes | An external reference to a merchant site for a specific cardholder. A key of merchant host and cuid will be used if none provided. The default can potentially violate a constraint with two accounts of the same merchant site. |
last_card_placed_id | number | no | ID of the last card placed on this account by the Virtual Browser System (VBS). |
account_link | object | no | One or more properties with key:value pairs that are required for authenticated a user. These properties are either included as part of initial account collection, or they are requested as part of a credential_request. An error will be returned if all properties are not provided for a given credential_request. The set of key:value pairs for a site are specified in the merchant site info returned from GET /merchant_sites as 'account_link'. If credentials are being saved as part of a credential_response, the corresponding envelope_id must be supplied as a header. |
See account response attributes.
Upsert account
const account = await session.updateAccount(1,{
"last_card_placed_id": 682904579,
"account_link": {
"username": "jsmith123",
"password": "BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI="
}
}, null, CARDHOLDER_SAFE_KEY);
PropertyBag body = new PropertyBag()
{
{ "last_card_placed_id", 682904579 }
};
CardSavrResponse<Account> account = await http.UpdateAccountAsync(body, CARDHOLDER_SAFE_KEY);
JsonObject body = Json.createObjectBuilder()
.add("last_card_placed_id", 682904579 )
.build();
JsonValue account = session.put("/cardsavr_accounts", body, null, null);
curl -d "{\"last_card_placed_id\":682904579,\"account_link\":{\"username\":\"jsmith123\",\"password\":\"BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=\"}}"
-X PUT -H "Content-Type: application/json"
-H "cardholder-safe-key: CARDHOLDER_SAFE_KEY"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_accounts/266084664
Path
PUT /cardsavr_accounts OR /cardsavr_accounts/{id}
Description
Upsert can be used to either update a account, create a new account, or return an existing account. Either an id or customer_key is required for upsert. The id (in path or body), along with an updated body, can be used to update an existing account; the customer_key (in body) can likewise be used to update a account, and can also be used to create a new account, if the customer_key does not match any existing accounts. If the id or customer_key provided corresponds to a pre-existing account and no updated information has been included in the body, the existing account will be returned.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
last_card_placed_id | number | ID of the last card placed on this account by the Virtual Browser System (VBS). |
account_link | object | One or more properties with key:value pairs that are required for authenticated a user. These properties are either included as part of initial account collection, or they are requested as part of a credential_request. An error will be returned if all properties are not provided for a given credential_request. The set of key:value pairs for a site are specified in the merchant site info returned from GET /merchant_sites as 'account_link'. If credentials are being saved as part of a credential_response, the corresponding envelope_id must be supplied as a header. |
See account response parameters.
Delete account
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_accounts/266084664
await session.deleteAccount(undefined);
CardSavrResponse<Account> account = await http.DeleteAccountAsync(undefined);
JsonValue account = session.delete("/cardsavr_accounts", undefined, null);
Path
DELETE /cardsavr_accounts/{id}
Description
Delete a account and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
See account response parameters.
Addresses
Address objects contain the billing address for a specific cardholder, and are used to populate billing address information on merchant sites. They are linked to cards and cardholders.
Get address
const addresses = await session.getAddresses(1491699994,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["cardholder"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<Addresses> addresses = await session.GetAddressesAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["cardholder"])}
JsonArray response = (JsonArray)session.get(1491699994, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 1491699994,
"address1": "ypEQiDFPsxFmRYIbCYSuEtVsLkpcMBotnLlTqlIAPFmJiBlTBXXLxbyKoMxPMYBASMCMVISQZqYyoWAaxXDiECkYXqWgyTDljIb",
"address2": "rrflIhFdmMaXSaEbFCIUuNkpXPsyUpsErNKizjqFRdTIwNraWaFOQAQXJywqWfRhpkICIVFznvAUBwQmcXVhXvhHAqVNMcFPMdx",
"city": "Seattle",
"subnational": "WA",
"postal_code": "98177",
"postal_other": "98177-0124",
"country": "USA",
"is_primary": true,
"first_name": "Jane",
"last_name": "Smith",
"email": "XjYggQTDsQzb@XhujRV.hIB",
"phone_number": "2065555555",
"created_on": "2021-08-24T04:39:22.973Z",
"last_updated_on": "2010-06-25T07:14:55.880Z",
"cardholder": {
"id": 425796635,
"type": "persistent_creds",
"first_name": "Jane",
"last_name": "Smith",
"email": "test_email@strivve.com",
"meta_key": "khModUQpsyT",
"webhook_url": "https://mywebhooks.com/this",
"custom_data": {
"bZtMPDVgJfSz": "bh#VWu!3RBCJlQAE[*0iJ[qI",
"ttsqzLeqTiFi": 64,
"NRTsqhRYODOE": false
},
"created_on": "2013-06-28T22:27:25.769Z",
"last_updated_on": "1992-08-04T11:01:03.145Z",
"cuid": "vyz"
}
}
Path
GET /cardsavr_addresses (batch) or GET /cardsavr_addresses/:id (singular)
Description
Returns the address specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable addresses, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- cardholder_ids
- is_primary
- first_name
- last_name
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/cardsavr_addresses?ids=1,2
Singular GET requests
Singular requests only return the address matching the id provided in the path.
Example GET request path:/cardsavr_addresses/1491699994
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this address. |
address1 | string | |
address2 | string | Second line of address, if one exists (e.g. apartment number). |
city | string | |
subnational | string | Subnational unit (i.e. state or province). |
postal_code | string | |
postal_other | string | E.g. last four digits in a zip-plus-four. |
country | string | |
is_primary | boolean | Indicates if this is the primary address of this cardholder, as a cardholder can be linked to multiple addresses. |
first_name | string | |
last_name | string | |
string | ||
phone_number | string | |
created_on | date | Date this site was created on |
last_updated_on | date | Date this site was last updated on |
cardholder_id | number (fk) cardholders | ID of the cardholder associated with this address. |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create address
const address = await session.createAddress({
"cardholder_id": 157855181,
"address1": "ypEQiDFPsxFmRYIbCYSuEtVsLkpcMBotnLlTqlIAPFmJiBlTBXXLxbyKoMxPMYBASMCMVISQZqYyoWAaxXDiECkYXqWgyTDljIb",
"address2": "rrflIhFdmMaXSaEbFCIUuNkpXPsyUpsErNKizjqFRdTIwNraWaFOQAQXJywqWfRhpkICIVFznvAUBwQmcXVhXvhHAqVNMcFPMdx",
"city": "Seattle",
"subnational": "WA",
"postal_code": "98177",
"postal_other": "98177-0124",
"country": "USA",
"is_primary": true,
"first_name": "Jane",
"last_name": "Smith",
"email": "XjYggQTDsQzb@XhujRV.hIB",
"phone_number": "2065555555"
});
PropertyBag body = new PropertyBag()
{
{ "cardholder_id", 157855181 },
{ "address1", "ypEQiDFPsxFmRYIbCYSuEtVsLkpcMBotnLlTqlIAPFmJiBlTBXXLxbyKoMxPMYBASMCMVISQZqYyoWAaxXDiECkYXqWgyTDljIb" },
{ "address2", "rrflIhFdmMaXSaEbFCIUuNkpXPsyUpsErNKizjqFRdTIwNraWaFOQAQXJywqWfRhpkICIVFznvAUBwQmcXVhXvhHAqVNMcFPMdx" },
{ "city", "Seattle" },
{ "subnational", "WA" },
{ "postal_code", "98177" },
{ "postal_other", "98177-0124" },
{ "country", "USA" },
{ "is_primary", true },
{ "first_name", "Jane" },
{ "last_name", "Smith" },
{ "email", "XjYggQTDsQzb@XhujRV.hIB" },
{ "phone_number", "2065555555" }
};
CardSavrResponse<Address> address = await http.CreateAddressAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("cardholder_id", 157855181 )
.add("address1", "ypEQiDFPsxFmRYIbCYSuEtVsLkpcMBotnLlTqlIAPFmJiBlTBXXLxbyKoMxPMYBASMCMVISQZqYyoWAaxXDiECkYXqWgyTDljIb" )
.add("address2", "rrflIhFdmMaXSaEbFCIUuNkpXPsyUpsErNKizjqFRdTIwNraWaFOQAQXJywqWfRhpkICIVFznvAUBwQmcXVhXvhHAqVNMcFPMdx" )
.add("city", "Seattle" )
.add("subnational", "WA" )
.add("postal_code", "98177" )
.add("postal_other", "98177-0124" )
.add("country", "USA" )
.add("is_primary", true )
.add("first_name", "Jane" )
.add("last_name", "Smith" )
.add("email", "XjYggQTDsQzb@XhujRV.hIB" )
.add("phone_number", "2065555555" )
.build();
JsonValue address = session.post("/cardsavr_addresses", body, null, null);
curl -d "{\"cardholder_id\":157855181,\"address1\":\"ypEQiDFPsxFmRYIbCYSuEtVsLkpcMBotnLlTqlIAPFmJiBlTBXXLxbyKoMxPMYBASMCMVISQZqYyoWAaxXDiECkYXqWgyTDljIb\",\"address2\":\"rrflIhFdmMaXSaEbFCIUuNkpXPsyUpsErNKizjqFRdTIwNraWaFOQAQXJywqWfRhpkICIVFznvAUBwQmcXVhXvhHAqVNMcFPMdx\",\"city\":\"Seattle\",\"subnational\":\"WA\",\"postal_code\":\"98177\",\"postal_other\":\"98177-0124\",\"country\":\"USA\",\"is_primary\":true,\"first_name\":\"Jane\",\"last_name\":\"Smith\",\"email\":\"XjYggQTDsQzb@XhujRV.hIB\",\"phone_number\":\"2065555555\"}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_addresses/
Path
POST /cardsavr_addresses
Description
Create a address and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
cardholder_id | number | yes | ID of the cardholder associated with this address. |
address1 | string | yes | |
address2 | string | no | Second line of address, if one exists (e.g. apartment number). |
city | string | yes | |
subnational | string | yes | Subnational unit (i.e. state or province). |
postal_code | string | yes | |
postal_other | string | no | E.g. last four digits in a zip-plus-four. |
country | string enum* | no | |
is_primary | boolean | yes | Indicates if this is the primary address of this cardholder, as a cardholder can be linked to multiple addresses. |
first_name | string | no | |
last_name | string | no | |
string | no | ||
phone_number | string | no |
See address response attributes.
string enum*
- usa
- USA
- us
- US
- canada
- Canada
- ca
- CA
Update address
const address = await session.updateAddress(1,{
"address1": "FpaDaJiKWkUetRBsmtkNqEBkdZyCDbGAwiRYILePbfxqOYwCSUbjimmeMMgbptHhBHEmGvlgQuTdbCcjzexWjWvMPtYjygCzllg",
"address2": "RYTgyXEULYCxjlHGEbAmPyIdmYVRRKOZjPpzHAlcqKQMhsZXkEuMuWWuXTUBOFXwQsyUspxRGfjxZJFNFNuygwdznZrZjSiFvNn",
"city": "Seattle",
"subnational": "WA",
"postal_code": "98177",
"postal_other": "98177-0124",
"country": "USA",
"is_primary": true,
"first_name": "Jane",
"last_name": "Smith",
"email": "QAqFByEIxBmo@WAxRCi.ipo",
"phone_number": "2065555555"
});
PropertyBag body = new PropertyBag()
{
{ "address1", "FpaDaJiKWkUetRBsmtkNqEBkdZyCDbGAwiRYILePbfxqOYwCSUbjimmeMMgbptHhBHEmGvlgQuTdbCcjzexWjWvMPtYjygCzllg" },
{ "address2", "RYTgyXEULYCxjlHGEbAmPyIdmYVRRKOZjPpzHAlcqKQMhsZXkEuMuWWuXTUBOFXwQsyUspxRGfjxZJFNFNuygwdznZrZjSiFvNn" },
{ "city", "Seattle" },
{ "subnational", "WA" },
{ "postal_code", "98177" },
{ "postal_other", "98177-0124" },
{ "country", "USA" },
{ "is_primary", true },
{ "first_name", "Jane" },
{ "last_name", "Smith" },
{ "email", "QAqFByEIxBmo@WAxRCi.ipo" },
{ "phone_number", "2065555555" }
};
CardSavrResponse<Address> address = await http.UpdateAddressAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("address1", "FpaDaJiKWkUetRBsmtkNqEBkdZyCDbGAwiRYILePbfxqOYwCSUbjimmeMMgbptHhBHEmGvlgQuTdbCcjzexWjWvMPtYjygCzllg" )
.add("address2", "RYTgyXEULYCxjlHGEbAmPyIdmYVRRKOZjPpzHAlcqKQMhsZXkEuMuWWuXTUBOFXwQsyUspxRGfjxZJFNFNuygwdznZrZjSiFvNn" )
.add("city", "Seattle" )
.add("subnational", "WA" )
.add("postal_code", "98177" )
.add("postal_other", "98177-0124" )
.add("country", "USA" )
.add("is_primary", true )
.add("first_name", "Jane" )
.add("last_name", "Smith" )
.add("email", "QAqFByEIxBmo@WAxRCi.ipo" )
.add("phone_number", "2065555555" )
.build();
JsonValue address = session.put("/cardsavr_addresses", body, null, null);
curl -d "{\"address1\":\"FpaDaJiKWkUetRBsmtkNqEBkdZyCDbGAwiRYILePbfxqOYwCSUbjimmeMMgbptHhBHEmGvlgQuTdbCcjzexWjWvMPtYjygCzllg\",\"address2\":\"RYTgyXEULYCxjlHGEbAmPyIdmYVRRKOZjPpzHAlcqKQMhsZXkEuMuWWuXTUBOFXwQsyUspxRGfjxZJFNFNuygwdznZrZjSiFvNn\",\"city\":\"Seattle\",\"subnational\":\"WA\",\"postal_code\":\"98177\",\"postal_other\":\"98177-0124\",\"country\":\"USA\",\"is_primary\":true,\"first_name\":\"Jane\",\"last_name\":\"Smith\",\"email\":\"QAqFByEIxBmo@WAxRCi.ipo\",\"phone_number\":\"2065555555\"}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_addresses/1491699994
Path
PUT /cardsavr_addresses OR /cardsavr_addresses/{id}
Description
Update a address and return the updated object. An id is required on every update request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
address1 | string | |
address2 | string | Second line of address, if one exists (e.g. apartment number). |
city | string | |
subnational | string | Subnational unit (i.e. state or province). |
postal_code | string | |
postal_other | string | E.g. last four digits in a zip-plus-four. |
country | string enum* | |
is_primary | boolean | Indicates if this is the primary address of this cardholder, as a cardholder can be linked to multiple addresses. |
first_name | string | |
last_name | string | |
string | ||
phone_number | string |
See address response parameters.
Delete address
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_addresses/1491699994
await session.deleteAddress(undefined);
CardSavrResponse<Address> address = await http.DeleteAddressAsync(undefined);
JsonValue address = session.delete("/cardsavr_addresses", undefined, null);
Path
DELETE /cardsavr_addresses/{id}
Description
Delete a address and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
See address response parameters.
Bins
A Bank Identification Number (BIN) object represents a BIN used by a financial institution in the CardSavr API. They are linked to cards and FIs and used for reporting purposes.
Get bin
const bins = await session.getBins(1397722725,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["financial_institution"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<Bins> bins = await session.GetBinsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["financial_institution"])}
JsonArray response = (JsonArray)session.get(1397722725, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 1397722725,
"custom_data": {
"jiOoJeVIzUPF": "n./{8{WB{3EpQUC=nEkXuKg+qGf.Bk.@",
"weTiLsxiaqwR": 40,
"IEnMdnuWOBOy": true
},
"created_on": "1985-12-01T13:42:58.530Z",
"last_updated_on": "1978-12-25T15:01:31.455Z",
"financial_institution": {
"id": 267334305,
"name": "zRTRtvEPlyqCbEkVaSeiCbJoVEIdFOuTnDoNUGVoTbswhVftZHWwlYVWfbXTZZE",
"description": "jMtlhrrNKLJEk",
"lookup_key": "KIpXoEROxciGDQpzHNZTzZTWwcafAgQFcCVZffwmyyOufFdoZDcXHJoEgcZmyUn",
"alternate_lookup_key": "chJrGjYybDtLKekaznhNdoeChSYVoyMSKSdTaLXaxDBSVookRxxqujIzEBSxcJZ",
"last_activity": "2003-02-04T08:23:14.446Z",
"created_on": "2011-02-13T15:54:28.316Z",
"last_updated_on": "1971-02-08T22:57:36.459Z"
},
"bank_identification_number": "34744400"
}
Path
GET /cardsavr_bins (batch) or GET /cardsavr_bins/:id (singular)
Description
Returns the bin specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable bins, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- financial_institution_ids
- bank_identification_numbers
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/cardsavr_bins?ids=1,2
Singular GET requests
Singular requests only return the bin matching the id provided in the path.
Example GET request path:/cardsavr_bins/1397722725
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this BIN. |
financial_institution_id | number (fk) financial institutions | ID of financial institution that this Bank Identification Number belongs to. |
custom_data | object | Custom data (e.g. brand, type) that can be added according to FI need. |
created_on | date | Date this site was created on |
last_updated_on | date | Date this site was last updated on |
bank_identification_number | string |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create bin
const bin = await session.createBin({
"financial_institution_id": 412839044,
"bank_identification_number": "34744400",
"custom_data": {
"jiOoJeVIzUPF": "n./{8{WB{3EpQUC=nEkXuKg+qGf.Bk.@",
"weTiLsxiaqwR": 40,
"IEnMdnuWOBOy": true
}
});
PropertyBag body = new PropertyBag()
{
{ "financial_institution_id", 412839044 },
{ "bank_identification_number", "34744400" }
};
CardSavrResponse<Bin> bin = await http.CreateBinAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("financial_institution_id", 412839044 )
.add("bank_identification_number", "34744400" )
.build();
JsonValue bin = session.post("/cardsavr_bins", body, null, null);
curl -d "{\"financial_institution_id\":412839044,\"bank_identification_number\":\"34744400\",\"custom_data\":{\"jiOoJeVIzUPF\":\"n./{8{WB{3EpQUC=nEkXuKg+qGf.Bk.@\",\"weTiLsxiaqwR\":40,\"IEnMdnuWOBOy\":true}}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_bins/
Path
POST /cardsavr_bins
Description
Create a bin and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
financial_institution_id | number | yes | ID of financial institution that this Bank Identification Number belongs to. |
bank_identification_number | string | yes | |
custom_data | object | no | Custom data (e.g. brand, type) that can be added according to FI need. |
Update bin
const bin = await session.updateBin(1,{
"financial_institution_id": 735777647,
"custom_data": {
"OaIhzKERvolW": "T0U%h7r",
"gecrJTaJEmMS": 40,
"qlIjtRJaSgVh": false
}
});
PropertyBag body = new PropertyBag()
{
{ "financial_institution_id", 735777647 }
};
CardSavrResponse<Bin> bin = await http.UpdateBinAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("financial_institution_id", 735777647 )
.build();
JsonValue bin = session.put("/cardsavr_bins", body, null, null);
curl -d "{\"financial_institution_id\":735777647,\"custom_data\":{\"OaIhzKERvolW\":\"T0U%h7r\",\"gecrJTaJEmMS\":40,\"qlIjtRJaSgVh\":false}}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_bins/1397722725
Path
PUT /cardsavr_bins OR /cardsavr_bins/{id}
Description
Update a bin and return the updated object. An id is required on every update request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
financial_institution_id | number | ID of financial institution that this Bank Identification Number belongs to. |
custom_data | object | Custom data (e.g. brand, type) that can be added according to FI need. |
Delete bin
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_bins/1397722725
await session.deleteBin(undefined);
CardSavrResponse<Bin> bin = await http.DeleteBinAsync(undefined);
JsonValue bin = session.delete("/cardsavr_bins", undefined, null);
Path
DELETE /cardsavr_bins/{id}
Description
Delete a bin and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Card Placement Results
Card Placement results are a flatted version of the jobs and its publily available meta data. Although sensitive data like the PAN and account creds are not available, all the details of the job are captured here for future reference after the corresponding entities may have been deleted.
Get card placement result
const cardplacementresults = await session.getCardPlacementResults(1947970693,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["financial_institution","merchant_site","cardsavr_bin"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<CardPlacementResults> cardplacementresults = await session.GetCardPlacementResultsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["financial_institution","merchant_site","cardsavr_bin"])}
JsonArray response = (JsonArray)session.get(1947970693, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 1947970693,
"merchant_site_hostname": "EIYsjGNMvWqHRmHoaZvXBKAGlVVngOkkYkgywkSZoxIRRMZimHLKVGyBepOfIPeCoLozvBpVAViXovprOKAHaCkXibbGYDUYnCQFphAAJtypVOBENIbCIJunfFysJbNmJDaRsJrroMlCPDVQkpbnIfeCkieHZoarNBeupspBCKWOxMzxTbYPYlsVyJqWGDHxJxDSkjarjKRvpAxOlLCxTBhqoscpxHQEzCKEootHvzHwOkXviwKhqHQzzSQHeQ",
"meta_key": "MB9810411",
"fi_name": "rMrXTUfOugMwYLQtVBzFSMVOlpUTXAEkVTYmqbJOXgTwyqpUuaLmDvFLhUCCtje",
"bank_identification_number": "67042473",
"cuid": "ilFRgdcmGXBnLY",
"par": "eEMMMkxkMkwkPwIUDqYICjjkNPKPZ",
"card_customer_key": "XMqklDgKdYYzuEifXhMbvpYe",
"account_customer_key": "REqVZuJ",
"status": "SUCCESSFUL",
"status_message": "Successful",
"termination_type": "BILLABLE",
"custom_data": {
"gSZCOzAPDTWs": ")88jQ,BPUOA",
"fZthtENujrvN": 35,
"bTiDzFzVdYcF": true
},
"time_elapsed": 339906507,
"first_6": "yhqaxkJpwIzZIsKcheUIkRwYhXLgJrwf",
"first_7": "McUqaGqHkUWUiIHafxNdsVhKCJCChGvZ",
"first_8": "ArtwLqVcyNolueETTCqhfBYsgWbpkhIt",
"trace": "YHrXjmzkfhq",
"agent_session_id": "eqsrXpnqAEdDmzFvkZQIe",
"email_sent": false,
"account_linked_on": "1997-01-20T17:55:47.347Z",
"job_ready_on": "1975-02-23T01:36:52.653Z",
"job_created_on": "1998-10-05T17:32:49.446Z",
"completed_on": "1979-03-15T22:00:29.287Z",
"created_on": "1998-07-24T00:01:59.908Z",
"last_updated_on": "1972-05-08T19:02:02.293Z",
"financial_institution": {
"id": 668173149,
"name": "yYCEVMSEkYjFBnmphKTHsUlFsAEAHOqkxfaeqpfTDTKLrMYnCxftSczjlGAQAHg",
"description": "UPHSdDWVKDcgdnNujME",
"lookup_key": "fCIhCkHikYVxWvUZYnolhZYRFVNMileUWeOvefCVHPeNMckETrjlXXaKTcTqoVV",
"alternate_lookup_key": "WWafuPezYixxiRNhsjvlUMgYbEendbZeoORCJKvJbxHXRbUkoVhlKBgiEfGJwYQ",
"last_activity": "1978-07-09T20:03:52.696Z",
"created_on": "1994-11-19T23:28:07.738Z",
"last_updated_on": "1970-02-07T04:57:24.989Z"
},
"merchant_site": {
"id": 812578964,
"name": "Amazon",
"note": "mlCwZPBYOjr",
"host": "amazon.com",
"tags": [
"&vK4{",
2,
"j.v3^wh$9NoI,)WJYe#_8tA"
],
"interface_type": "vbs",
"job_type": "BILL_PAY",
"required_form_fields": [
"email",
"phone_number",
"card_data",
"cvv",
"billing_address",
"postal_code"
],
"images": [
{
"url": "https://d1t7g1oas7m24a.cloudfront.net/tiles/dollarshaveclub.com?width=128&version=21f917315911eec1b1705bc7784ce861579cff2b",
"width": 128,
"grayscale": false
},
{
"url": "https://d1t7g1oas7m24a.cloudfront.net/tiles/dollarshaveclub.com?width=32&version=21f917315911eec1b1705bc7784ce861579cff2b",
"width": 32,
"grayscale": false
}
],
"account_link": [
{
"key_name": "username",
"label": "Username",
"type": "initial_account_link"
},
{
"key_name": "password",
"label": "Password",
"type": "initial_account_link",
"secret": true
},
{
"key_name": "otp",
"label": "One Time Passcode",
"type": ""
}
],
"messages": {
"mfa_label": "Additional information required, this code may be sent to your phone or email address.",
"additional_info_message": "",
"auth_message": "Linking account."
},
"script_directory": "iCFstlHvsTMtmQHgzbCKXjPDQrZ",
"record_final_site_artifacts": false,
"puppeteer_screenshot": true,
"login_page": "https://www.merchantsite.com/login",
"forgot_password_page": "https://www.merchantsite.com/forgot_password",
"credit_card_page": "https://www.merchantsite.com/credit_card",
"wallet_page": "WJpZBvjmSyRucdMvRIdzzMEFJo",
"merchant_sso_group": "WszkadC",
"tier": 845790445,
"cookie_caching_scheme": "none",
"dynamic_viewport": true,
"use_puppeteer": false
},
"cardsavr_bin": {
"id": 613109741,
"custom_data": {
"KkHQspkKgmNV": ".DUtTW1U5Cm}_NO(hT5",
"IBDixEdtEUyc": 80,
"CjXKbmZLeHdp": false
},
"created_on": "2023-12-19T17:36:44.229Z",
"last_updated_on": "2001-02-23T00:27:46.535Z",
"bank_identification_number": "6821244"
},
"place_card_on_single_site_job_id": 18768762
}
Path
GET /card_placement_results (batch) or GET /card_placement_results/:id (singular)
Description
Returns the card placement result specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable card placement results, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- merchant_site_hostnames
- merchant_site_hostname
- meta_key
- fi_name
- bank_identification_numbers
- cuids
- pars
- card_customer_keys
- account_customer_keys
- statuses
- status
- termination_type
- termination_types_include / termination_types_exclude
- first_6
- first_7
- first_8
- place_card_on_single_site_job_ids
- financial_institution_ids
- merchant_site_ids
- agent_session_id
- email_sent
- account_linked_on_min / account_linked_on_max
- job_ready_on_min / job_ready_on_max
- job_created_on_min / job_created_on_max
- completed_on_min / completed_on_max
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/card_placement_results?ids=1,2
Singular GET requests
Singular requests only return the card placement result matching the id provided in the path.
Example GET request path:/card_placement_results/1947970693
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this card placement result. |
merchant_site_hostname | string | |
meta_key | string | Key used for billing record identification; automatically generated during card creation. |
fi_name | string | |
bank_identification_number | string | |
cuid | string | External unique ID for cardholder--can be account_id, email address, phone number, etc. A random number will be gnenerated if not provided. |
par | string | |
card_customer_key | string | Unique customer reference for this card. A random number will be generated and returned if not provided |
account_customer_key | string | An external reference to a merchant site for a specific cardholder. A key of merchant host and cuid will be used if none provided. The default can potentially violate a constraint with two accounts of the same merchant site. |
status | string | Status of job (when it terminated). |
status_message | string | Human readable representation of the job's status. |
termination_type | string | Final termination status of a job. (BILLABLE, SITE_INTERACTION_FAILURE, USER_DATA_FAILURE, PROCESS FAILURE) |
custom_data | object | |
time_elapsed | number | |
first_6 | string | First six digits of card number. |
first_7 | string | First seven digits of card number. |
first_8 | string | First eight digits of card number. |
trace | string | The trace key follows jobs as they are processed from beginning to end. This helps with debugging the logs. |
financial_institution_id | number (fk) financial institutions | |
merchant_site_id | number (fk) merchant sites | |
agent_session_id | string | |
email_sent | boolean | |
account_linked_on | date | Timestamp from when the account for this job is linked -- this could use persistent or user provided credentials |
job_ready_on | date | Timestamp from when initial credentials have been set on the account for the job. |
job_created_on | date | Timestamp from when the job was created. |
completed_on | date | |
created_on | date | Date this job result was created on |
last_updated_on | date | Date this job result was last updated on |
place_card_on_single_site_job_id | number |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Cardholder sessions
A record of information associated with the session of a carholder -- it terminates after explicit completion or 15 minutes of inactivity.
Get cardholder session
const cardholdersessions = await session.getCardholderSessions(243495999,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["cardholder","financial_institution"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<CardholderSessions> cardholdersessions = await session.GetCardholderSessionsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["cardholder","financial_institution"])}
JsonArray response = (JsonArray)session.get(243495999, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 243495999,
"successful_jobs": 880155574,
"failed_jobs": 461747565,
"clickstream": [
{
"uyEDhCKJocJU": "+WpkFKFn1Z",
"MZLNOpLNkMxV": 85,
"QeDOBdYNldsp": true
},
{
"hYhodOfRBYxg": "tDRpPHG}WEUm.p{1ZxQ{,_",
"rCFpGFwSqCcY": 1,
"zoVHcDtLfbCP": false
},
{
"NNDqmWcBgxSF": "z!!(~7_(=qgr^ZQ",
"LJCkMwdPOuBG": 32,
"lYkyOvDDTjqK": true
}
],
"closed_on": "1983-10-07T23:13:26.298Z",
"custom_data": {
"gAWaHBAzheEj": "v$Xjm_M[Ix_/^=A4.9Q",
"lzBnSDnpJdYu": 56,
"WbEmamPZgJrp": false
},
"created_on": "2017-07-04T15:53:21.457Z",
"last_updated_on": "2023-03-08T01:06:37.050Z",
"cardholder": {
"id": 677820644,
"type": "persistent_nocreds",
"first_name": "Jane",
"last_name": "Smith",
"email": "test_email@strivve.com",
"meta_key": "WKsQVbgVN",
"webhook_url": "https://mywebhooks.com/this",
"custom_data": {
"kjrfJrTmYZzK": "I)y-t/b1J[pTUM#,",
"rqkenJrCnGJH": 66,
"ZqkzFQeXhzIo": false
},
"created_on": "1970-03-31T02:21:57.690Z",
"last_updated_on": "1994-12-24T15:01:39.315Z",
"cuid": "pPBGTpqyjzJcHsKSsZI"
},
"financial_institution": {
"id": 489234121,
"name": "DrxksIiDOZsWXsuPrcDZjAlhWsZHCzMcsyMcYKQnrCEqUdvTgiTmWlmYNtgxDUt",
"description": "gHjxZUMLRLdGPPMil",
"lookup_key": "kzhPImWPZCrMnTyuUODYGUlpPKeDlUdbGbQLYsAQgFfWJOzqVBQoHTBBzdFenuW",
"alternate_lookup_key": "AuRddWluqSBSraTCakbNmLoeaAnryDZwNQwxmESMIjJJipmWLTsGwQoPNAdmSRW",
"last_activity": "1973-08-04T03:16:58.206Z",
"created_on": "1986-07-16T05:29:06.944Z",
"last_updated_on": "1991-09-05T14:18:16.416Z"
},
"cuid": "IHwdTsuL"
}
Path
GET /cardholder_sessions (batch) or GET /cardholder_sessions/:id (singular)
Description
Returns the cardholder session specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable cardholder sessions, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- cuid
- cardholder_id
- financial_institution_id
- closed_on_min / closed_on_max
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/cardholder_sessions?ids=1,2
Singular GET requests
Singular requests only return the cardholder session matching the id provided in the path.
Example GET request path:/cardholder_sessions/243495999
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this card placement result. |
successful_jobs | number | |
failed_jobs | number | |
cardholder_id | number (fk) cardholders | |
financial_institution_id | number (fk) financial institutions | |
clickstream | array | Click stream events and their corresponding timestamps |
closed_on | date | Timestamp at which this cardholder session was closed |
custom_data | object | Additional data that can be added to the cardholder if needed. |
created_on | date | Date this job result was created on |
last_updated_on | date | Date this job result was last updated on |
cuid | string |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Upsert cardholder session
const cardholdersession = await session.updateCardholderSession(1,{
"successful_jobs": 1170130296,
"failed_jobs": 189466969,
"clickstream": [
{
"chYEgWePeVzn": "]]9u4BjyBM",
"qJmOiNcXKKdL": 11,
"CwUJloUviJge": true
},
{
"mdPXWmvdEyUL": "CN78vA$T_}A37@qV2wuo9uCLSV",
"UcknuLAadkNc": 73,
"SAdyVDHDQlUy": false
},
{
"FtIkrvedOYji": "n1Et#Jv$HZT_",
"dWXnlkODZNnK": 30,
"XpeLCGFIJDgM": true
}
]
});
PropertyBag body = new PropertyBag()
{
{ "successful_jobs", 1170130296 },
{ "failed_jobs", 189466969 }
};
CardSavrResponse<CardholderSession> cardholdersession = await http.UpdateCardholderSessionAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("successful_jobs", 1170130296 )
.add("failed_jobs", 189466969 )
.build();
JsonValue cardholdersession = session.put("/cardholder_sessions", body, null, null);
curl -d "{\"successful_jobs\":1170130296,\"failed_jobs\":189466969,\"clickstream\":[{\"chYEgWePeVzn\":\"]]9u4BjyBM\",\"qJmOiNcXKKdL\":11,\"CwUJloUviJge\":true},{\"mdPXWmvdEyUL\":\"CN78vA$T_}A37@qV2wuo9uCLSV\",\"UcknuLAadkNc\":73,\"SAdyVDHDQlUy\":false},{\"FtIkrvedOYji\":\"n1Et#Jv$HZT_\",\"dWXnlkODZNnK\":30,\"XpeLCGFIJDgM\":true}]}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardholder_sessions/243495999
Path
PUT /cardholder_sessions OR /cardholder_sessions/{id}
Description
Upsert can be used to either update a cardholder session, create a new cardholder session, or return an existing cardholder session. Either an id or customer_key is required for upsert. The id (in path or body), along with an updated body, can be used to update an existing cardholder session; the customer_key (in body) can likewise be used to update a cardholder session, and can also be used to create a new cardholder session, if the customer_key does not match any existing cardholder sessions. If the id or customer_key provided corresponds to a pre-existing cardholder session and no updated information has been included in the body, the existing cardholder session will be returned.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
successful_jobs | number | |
failed_jobs | number | |
clickstream | array | Click stream events and their corresponding timestamps |
See cardholder session response parameters.
Cards
A card object contains information about a payment card for a specific cardholder. Card objects are used to populate payment information on merchant sites.
Get card
const cards = await session.getCards(367162066,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["cardholder","cardsavr_address","cardsavr_bin"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<Cards> cards = await session.GetCardsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["cardholder","cardsavr_address","cardsavr_bin"])}
JsonArray response = (JsonArray)session.get(367162066, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 367162066,
"type": "Mastercard",
"expiration_month": 12,
"expiration_year": 24,
"name_on_card": "Jane Smith",
"nickname": "Jane's VISA",
"custom_data": {
"RuhBBJrWafpz": "rX#rW!GB8",
"pyErFMiIpgKn": 96,
"YcJFUHCHxyHT": false
},
"created_on": "1985-12-19T18:55:30.820Z",
"last_updated_on": "2024-04-25T23:15:50.467Z",
"cardholder": {
"id": 279093433,
"type": "persistent_nocreds",
"first_name": "Jane",
"last_name": "Smith",
"email": "test_email@strivve.com",
"meta_key": "UKMAPrwGxqAWoKaZYDRJuYWM",
"webhook_url": "https://mywebhooks.com/this",
"custom_data": {
"dIykSyMWlHDk": "V)P+3Y6r)[",
"fMKURMdQgasK": 65,
"elJlxczNmpxv": false
},
"created_on": "2005-01-23T09:32:59.321Z",
"last_updated_on": "2004-12-26T14:40:21.292Z",
"cuid": "TOGONYZkpsnMLlTFgUVbsYcXOZDsD"
},
"cardsavr_address": {
"id": 1051375920,
"address1": "BgDQfXDkSvZJsDEPeZuVHUFJcTmrACAmSeumkflNUZuHpvxcczHIJoKgKhRNQzJuiwybjeanzXIKzoFCPAGFZPuFFhZUWuDgTpm",
"address2": "QaGOTgysRoDeHjDxUzAcFxDWTEvjybiwulHyxowTrDwQNVDEPjGJRUHrNPkUIlowHGvZmAuHUChBzqYyfkRveJJaNnItHFEixug",
"city": "Seattle",
"subnational": "WA",
"postal_code": "98177",
"postal_other": "98177-0124",
"country": "USA",
"is_primary": true,
"first_name": "Jane",
"last_name": "Smith",
"email": "kRKIYqxCtVpp@bLSAOD.sfN",
"phone_number": "2065555555",
"created_on": "1984-04-19T09:01:10.810Z",
"last_updated_on": "2021-06-01T15:32:38.787Z"
},
"cardsavr_bin": {
"id": 402685629,
"custom_data": {
"aqZGilDssVkx": "n%Q*_0-G3MgRyksqe1CY%XTyO{W",
"sMViEdNVbhST": 78,
"sYMclrTlPYcq": false
},
"created_on": "2008-10-12T16:05:29.869Z",
"last_updated_on": "1987-12-18T11:25:32.284Z",
"bank_identification_number": "66211757"
},
"par": "wcjrormelZptYiACKQVweWTXNysCJ",
"customer_key": "zWAHD"
}
Path
GET /cardsavr_cards (batch) or GET /cardsavr_cards/:id (singular)
Description
Returns the card specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable cards, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- cardholder_ids
- address_ids
- bin_ids
- pars
- customer_keys
- types
- type
- nickname
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/cardsavr_cards?ids=1,2
Singular GET requests
Singular requests only return the card matching the id provided in the path.
Example GET request path:/cardsavr_cards/367162066
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this card. |
address_id | number (fk) addresses | ID of address associated with this card. |
bin_id | number (fk) bins | ID of BIN associated with this card. |
type | string | Type of card (e.g. Visa), automatically filled in by CardSavr. |
expiration_month | string | |
expiration_year | string | |
name_on_card | string | |
nickname | string | |
custom_data | object | Meta-data that can be added to the card if needed. |
created_on | date | Date this site was created on |
last_updated_on | date | Date this site was last updated on |
cardholder_id | number (fk) cardholders | ID of cardholder associated with this card. |
par | string | Unique Personal Account Reference number for this card, to be used for card lookup. Generated automatically from PAN, expiration date, and username if using the SDK. |
customer_key | string | Unique customer reference for this card. A random number will be generated and returned if not provided |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create card
const card = await session.createCard({
"cardholder_id": 893707349,
"address_id": 421801386,
"bin_id": 279961730,
"par": "wcjrormelZptYiACKQVweWTXNysCJ",
"customer_key": "zWAHD",
"pan": "4111111111111111",
"cvv": "111",
"expiration_month": 12,
"expiration_year": 24,
"name_on_card": "Jane Smith",
"nickname": "Jane's VISA",
"custom_data": {
"RuhBBJrWafpz": "rX#rW!GB8",
"pyErFMiIpgKn": 96,
"YcJFUHCHxyHT": false
}
}, CARDHOLDER_SAFE_KEY);
PropertyBag body = new PropertyBag()
{
{ "cardholder_id", 893707349 },
{ "address_id", 421801386 },
{ "bin_id", 279961730 },
{ "par", "wcjrormelZptYiACKQVweWTXNysCJ" },
{ "customer_key", "zWAHD" },
{ "pan", "4111111111111111" },
{ "cvv", "111" },
{ "expiration_month", 12 },
{ "expiration_year", 24 },
{ "name_on_card", "Jane Smith" },
{ "nickname", "Jane's VISA" }
};
CardSavrResponse<Card> card = await http.CreateCardAsync(body, CARDHOLDER_SAFE_KEY);
JsonObject body = Json.createObjectBuilder()
.add("cardholder_id", 893707349 )
.add("address_id", 421801386 )
.add("bin_id", 279961730 )
.add("par", "wcjrormelZptYiACKQVweWTXNysCJ" )
.add("customer_key", "zWAHD" )
.add("pan", "4111111111111111" )
.add("cvv", "111" )
.add("expiration_month", 12 )
.add("expiration_year", 24 )
.add("name_on_card", "Jane Smith" )
.add("nickname", "Jane's VISA" )
.build();
JsonValue card = session.post("/cardsavr_cards", body, null, null);
curl -d "{\"cardholder_id\":893707349,\"address_id\":421801386,\"bin_id\":279961730,\"par\":\"wcjrormelZptYiACKQVweWTXNysCJ\",\"customer_key\":\"zWAHD\",\"pan\":\"4111111111111111\",\"cvv\":\"111\",\"expiration_month\":12,\"expiration_year\":24,\"name_on_card\":\"Jane Smith\",\"nickname\":\"Jane's VISA\",\"custom_data\":{\"RuhBBJrWafpz\":\"rX#rW!GB8\",\"pyErFMiIpgKn\":96,\"YcJFUHCHxyHT\":false}}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-cardholder-safe-key: CARDHOLDER_SAFE_KEY"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_cards/
Path
POST /cardsavr_cards
Description
Create a card and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
cardholder_id | number | yes | ID of cardholder associated with this card. |
address_id | number | no | ID of address associated with this card. |
bin_id | number | no | ID of BIN associated with this card. |
par | string | no | Unique Personal Account Reference number for this card, to be used for card lookup. Generated automatically from PAN, expiration date, and username if using the SDK. |
customer_key | string | yes | Unique customer reference for this card. A random number will be generated and returned if not provided |
pan | string | yes | Personal Account Number (PAN) of this card. |
cvv | string | no | |
expiration_month | string enum** | yes | |
expiration_year | string | yes | |
name_on_card | string | yes | |
nickname | string | yes | |
custom_data | object | no | Meta-data that can be added to the card if needed. |
string enum*
- Visa
- Mastercard
- American Express
- Unknown Type
string enum**
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
Upsert card
const card = await session.updateCard(1,{
"address_id": 2011076689,
"bin_id": 1224955123,
"cvv": "111",
"expiration_month": 12,
"expiration_year": 24,
"name_on_card": "Jane Smith",
"nickname": "Jane's VISA",
"custom_data": {
"CNaKjYTYmOXo": "=fLp!uv81R%Yhi",
"EYqYtpTKIcmF": 91,
"GrBUhfIqNjUt": true
},
"pan": "4111111111111111"
}, CARDHOLDER_SAFE_KEY);
PropertyBag body = new PropertyBag()
{
{ "address_id", 2011076689 },
{ "bin_id", 1224955123 },
{ "cvv", "111" },
{ "expiration_month", 12 },
{ "expiration_year", 24 },
{ "name_on_card", "Jane Smith" },
{ "nickname", "Jane's VISA" },
{ "pan", "4111111111111111" }
};
CardSavrResponse<Card> card = await http.UpdateCardAsync(body, CARDHOLDER_SAFE_KEY);
JsonObject body = Json.createObjectBuilder()
.add("address_id", 2011076689 )
.add("bin_id", 1224955123 )
.add("cvv", "111" )
.add("expiration_month", 12 )
.add("expiration_year", 24 )
.add("name_on_card", "Jane Smith" )
.add("nickname", "Jane's VISA" )
.add("pan", "4111111111111111" )
.build();
JsonValue card = session.put("/cardsavr_cards", body, null, null);
curl -d "{\"address_id\":2011076689,\"bin_id\":1224955123,\"cvv\":\"111\",\"expiration_month\":12,\"expiration_year\":24,\"name_on_card\":\"Jane Smith\",\"nickname\":\"Jane's VISA\",\"custom_data\":{\"CNaKjYTYmOXo\":\"=fLp!uv81R%Yhi\",\"EYqYtpTKIcmF\":91,\"GrBUhfIqNjUt\":true},\"pan\":\"4111111111111111\"}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_cards/367162066
Path
PUT /cardsavr_cards OR /cardsavr_cards/{id}
Description
Upsert can be used to either update a card, create a new card, or return an existing card. Either an id or customer_key is required for upsert. The id (in path or body), along with an updated body, can be used to update an existing card; the customer_key (in body) can likewise be used to update a card, and can also be used to create a new card, if the customer_key does not match any existing cards. If the id or customer_key provided corresponds to a pre-existing card and no updated information has been included in the body, the existing card will be returned.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
address_id | number | ID of address associated with this card. |
bin_id | number | ID of BIN associated with this card. |
cvv | string | |
expiration_month | string enum** | |
expiration_year | string | |
name_on_card | string | |
nickname | string | |
custom_data | object | Meta-data that can be added to the card if needed. |
Delete card
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_cards/367162066
await session.deleteCard(undefined);
CardSavrResponse<Card> card = await http.DeleteCardAsync(undefined);
JsonValue card = session.delete("/cardsavr_cards", undefined, null);
Path
DELETE /cardsavr_cards/{id}
Description
Delete a card and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Cardholders
Cardholders are the end-users of the CardSavr API, who can have their their payment information updated on merchant site(s). Cardholders can be linked to cards, accounts, and addresses.
Get cardholder
const cardholders = await session.getCardholders(1872752000,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["financial_institution","integrator"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<Cardholders> cardholders = await session.GetCardholdersAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["financial_institution","integrator"])}
JsonArray response = (JsonArray)session.get(1872752000, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 1872752000,
"type": "ephemeral",
"first_name": "Jane",
"last_name": "Smith",
"email": "test_email@strivve.com",
"meta_key": "Itrf",
"webhook_url": "https://mywebhooks.com/this",
"custom_data": {
"mfShmWbzeUFu": "wKkj/Qu3oU&[aA,Q4Y@$i0",
"zwqjNMyPRuyY": 24,
"TxmhNRYLHNxl": false
},
"created_on": "2013-08-28T20:50:02.288Z",
"last_updated_on": "2001-04-06T23:47:37.275Z",
"financial_institution": {
"id": 1269399462,
"name": "yHAoswbvRQXvqTDxeIPfilwLWsukmTMwfZRWqbTbWfQfOaPfwirtFjWPWJHguLG",
"description": "YUGLHWiOC",
"lookup_key": "IkgCLZhCpwTTFkIoIWUiIWyAUoTMBwneDwVGKTqCECByDKoisxvssXxcVopuPmx",
"alternate_lookup_key": "AlIFZjVJXlzOAxkxTMmfNBpKLcLIATOOPIlwIqPpdSsdwsPbHayccyuvQNLBYbR",
"last_activity": "1990-07-12T01:45:43.878Z",
"created_on": "2011-06-10T08:56:52.021Z",
"last_updated_on": "2004-12-17T01:38:02.167Z"
},
"integrator": {
"id": 698724959,
"name": "oBMSFhvGaMeGbPafZHuoaqbyqvjAemvQIazIsxarbOEcMAVYF",
"description": "CZdWXMjVuJKNgyjGPvvQvWdJoDZTEr",
"current_key": "uYB/5R6WtPcOisWYP76CQQi4PFN32M98byphyIV8Y8w=",
"key_lifetime": 288,
"next_rotation_on": "2011-03-05T22:27:19.969Z",
"created_on": "1999-01-21T05:29:49.909Z",
"last_updated_on": "1978-08-24T06:12:25.753Z"
},
"cuid": "PZkDarkwBWMwmafUtgWQNVr"
}
Path
GET /cardholders (batch) or GET /cardholders/:id (singular)
Description
Returns the cardholder specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable cardholders, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- financial_institution_ids
- financial_institution_id
- cuid
- type
- first_name
- last_name
- meta_key
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/cardholders?ids=1,2
Singular GET requests
Singular requests only return the cardholder matching the id provided in the path.
Example GET request path:/cardholders/1872752000
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this cardholder. |
financial_institution_id | number (fk) financial institutions | |
type | string | It is critical to understand the behavior associated with each cardholder type. The default, 'ephemeral', cardholder is deleted along with all its associated entities upon session termination. 'persistent_credentials' cardholders are not removed automatically, but their associated cards are. 'persistent_all' cardholders are not removed and neither are any of their associated entities. If not storing CardSavr ids within your application, you can look up cards and accounts using the corresponding customer_key. |
first_name | string | |
last_name | string | |
string | ||
meta_key | string | Key used for billing record identification; automatically generated during card creation. |
webhook_url | string | A cardholder specific url for posting job reults following the end of a session. This overrides the FI global settiings in the portal. |
custom_data | object | Additional data that can be added to the cardholder if needed. |
created_on | date | Date this site was created on |
last_updated_on | date | Date this site was last updated on |
cuid | string | External unique ID for cardholder--can be account_id, email address, phone number, etc. A random number will be gnenerated if not provided. |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create cardholder
const cardholder = await session.createCardholder({
"cuid": "PZkDarkwBWMwmafUtgWQNVr",
"type": "ephemeral",
"first_name": "Jane",
"last_name": "Smith",
"email": "test_email@strivve.com",
"meta_key": "Itrf",
"webhook_url": "https://mywebhooks.com/this",
"custom_data": {
"mfShmWbzeUFu": "wKkj/Qu3oU&[aA,Q4Y@$i0",
"zwqjNMyPRuyY": 24,
"TxmhNRYLHNxl": false
}
});
PropertyBag body = new PropertyBag()
{
{ "cuid", "PZkDarkwBWMwmafUtgWQNVr" },
{ "type", "ephemeral" },
{ "first_name", "Jane" },
{ "last_name", "Smith" },
{ "email", "test_email@strivve.com" },
{ "meta_key", "Itrf" },
{ "webhook_url", "https://mywebhooks.com/this" }
};
CardSavrResponse<Cardholder> cardholder = await http.CreateCardholderAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("cuid", "PZkDarkwBWMwmafUtgWQNVr" )
.add("type", "ephemeral" )
.add("first_name", "Jane" )
.add("last_name", "Smith" )
.add("email", "test_email@strivve.com" )
.add("meta_key", "Itrf" )
.add("webhook_url", "https://mywebhooks.com/this" )
.build();
JsonValue cardholder = session.post("/cardholders", body, null, null);
curl -d "{\"cuid\":\"PZkDarkwBWMwmafUtgWQNVr\",\"type\":\"ephemeral\",\"first_name\":\"Jane\",\"last_name\":\"Smith\",\"email\":\"test_email@strivve.com\",\"meta_key\":\"Itrf\",\"webhook_url\":\"https://mywebhooks.com/this\",\"custom_data\":{\"mfShmWbzeUFu\":\"wKkj/Qu3oU&[aA,Q4Y@$i0\",\"zwqjNMyPRuyY\":24,\"TxmhNRYLHNxl\":false}}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardholders/
Path
POST /cardholders
Description
Create a cardholder and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
cuid | string | yes | External unique ID for cardholder--can be account_id, email address, phone number, etc. A random number will be gnenerated if not provided. |
type | string enum* | no | It is critical to understand the behavior associated with each cardholder type. The default, 'ephemeral', cardholder is deleted along with all its associated entities upon session termination. 'persistent_credentials' cardholders are not removed automatically, but their associated cards are. 'persistent_all' cardholders are not removed and neither are any of their associated entities. If not storing CardSavr ids within your application, you can look up cards and accounts using the corresponding customer_key. |
first_name | string | no | |
last_name | string | no | |
string | no | ||
meta_key | string | no | Key used for billing record identification; automatically generated during card creation. |
webhook_url | string | no | A cardholder specific url for posting job reults following the end of a session. This overrides the FI global settiings in the portal. |
custom_data | object | no | Additional data that can be added to the cardholder if needed. |
See cardholder response attributes.
string enum*
- ephemeral
- persistent_nocreds
- persistent_creds
- persistent_all
Upsert cardholder
const cardholder = await session.updateCardholder(1,{
"type": "persistent_nocreds",
"first_name": "Jane",
"last_name": "Smith",
"email": "test_email@strivve.com",
"meta_key": "D",
"webhook_url": "https://mywebhooks.com/this",
"custom_data": {
"bTBqVwpYDQLN": "{o)8F",
"MQYgxruuwZfC": 77,
"uQWcryTLWLDF": false
}
});
PropertyBag body = new PropertyBag()
{
{ "type", "persistent_nocreds" },
{ "first_name", "Jane" },
{ "last_name", "Smith" },
{ "email", "test_email@strivve.com" },
{ "meta_key", "D" },
{ "webhook_url", "https://mywebhooks.com/this" }
};
CardSavrResponse<Cardholder> cardholder = await http.UpdateCardholderAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("type", "persistent_nocreds" )
.add("first_name", "Jane" )
.add("last_name", "Smith" )
.add("email", "test_email@strivve.com" )
.add("meta_key", "D" )
.add("webhook_url", "https://mywebhooks.com/this" )
.build();
JsonValue cardholder = session.put("/cardholders", body, null, null);
curl -d "{\"type\":\"persistent_nocreds\",\"first_name\":\"Jane\",\"last_name\":\"Smith\",\"email\":\"test_email@strivve.com\",\"meta_key\":\"D\",\"webhook_url\":\"https://mywebhooks.com/this\",\"custom_data\":{\"bTBqVwpYDQLN\":\"{o)8F\",\"MQYgxruuwZfC\":77,\"uQWcryTLWLDF\":false}}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardholders/1872752000
Path
PUT /cardholders OR /cardholders/{id}
Description
Upsert can be used to either update a cardholder, create a new cardholder, or return an existing cardholder. Either an id or cuid is required for upsert. The id (in path or body), along with an updated body, can be used to update an existing cardholder; the cuid (in body) can likewise be used to update a cardholder, and can also be used to create a new cardholder, if the cuid does not match any existing cardholders. If the id or cuid provided corresponds to a pre-existing cardholder and no updated information has been included in the body, the existing cardholder will be returned.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
type | string enum* | It is critical to understand the behavior associated with each cardholder type. The default, 'ephemeral', cardholder is deleted along with all its associated entities upon session termination. 'persistent_credentials' cardholders are not removed automatically, but their associated cards are. 'persistent_all' cardholders are not removed and neither are any of their associated entities. If not storing CardSavr ids within your application, you can look up cards and accounts using the corresponding customer_key. |
first_name | string | |
last_name | string | |
string | ||
meta_key | string | Key used for billing record identification; automatically generated during card creation. |
webhook_url | string | A cardholder specific url for posting job reults following the end of a session. This overrides the FI global settiings in the portal. |
custom_data | object | Additional data that can be added to the cardholder if needed. |
See cardholder response parameters.
Delete cardholder
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardholders/1872752000
await session.deleteCardholder(undefined);
CardSavrResponse<Cardholder> cardholder = await http.DeleteCardholderAsync(undefined);
JsonValue cardholder = session.delete("/cardholders", undefined, null);
Path
DELETE /cardholders/{id}
Description
Delete a cardholder and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
See cardholder response parameters.
Users
Users are internal entities, such as agents or admins, that can perform such functions as creating and deleting cardholders, fetching merchant sites, creating jobs, etc.
Get user
const users = await session.getUsers(665640954,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["financial_institution"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<Users> users = await session.GetUsersAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["financial_institution"])}
JsonArray response = (JsonArray)session.get(665640954, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 665640954,
"first_name": "Joe",
"last_name": "Smith",
"last_login_time": "2002-06-25T22:30:43.795Z",
"is_locked": true,
"password_lifetime": 196,
"email": "test_email@strivve.com",
"is_password_update_required": false,
"role": "admin",
"next_rotation_on": "2009-05-30T23:55:01.284Z",
"created_on": "1979-11-01T03:28:46.649Z",
"last_updated_on": "1991-09-25T07:30:18.554Z",
"username": "jsmith123",
"financial_institution": {
"id": 1694870516,
"name": "mzWLTBGKbUnprdnvkFgHGyfneUDfSmhHOzMMCPsnZjKksqRyNYBFhLcUVOLaSsz",
"description": "dpfMaJlKKsgqYbwaGfFFXnUkqJtV",
"lookup_key": "ANlsdhICAvgYWcYbONiVNBDyNJPLyHWlTNvleJLgkHRIxhGOgkMEpXmsDvxjxnQ",
"alternate_lookup_key": "kXDSZbHlLPkDGrLEcfbxwpRTrykjVaSfAuivdcuoLJwSyJpHNyFvRZqiOCIveJD",
"last_activity": "1995-02-28T15:00:01.038Z",
"created_on": "2017-01-13T14:22:43.903Z",
"last_updated_on": "1990-08-05T21:33:45.346Z"
}
}
Path
GET /cardsavr_users (batch) or GET /cardsavr_users/:id (singular)
Description
Returns the user specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable users, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- financial_institution_ids
- usernames
- username
- first_name
- last_name
- last_login_time_min / last_login_time_max
- is_locked
- is_password_update_required
- role
- roles_include / roles_exclude
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/cardsavr_users?ids=1,2
Singular GET requests
Singular requests only return the user matching the id provided in the path.
Example GET request path:/cardsavr_users/665640954
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this user. |
financial_institution_id | number (fk) financial institutions | |
first_name | string | |
last_name | string | |
last_login_time | date | |
is_locked | boolean | |
password_lifetime | number | Length of time that password will remain valid. |
string | ||
is_password_update_required | boolean | |
role | string | User role (cardholder_agent, cardholder_sso_agent or customer_agent) determines the user's ability to access certain endpoints and perform certain operations within the CardSavr API. cardholder_agents can create cardholders, create card's addresses for those cardholders, create accounts for those cardholders, and post jobs for those cardholders. cardholder_sso_agents are like cardholder_agent, but cannot create cardholder or cards. customer_agents can peform all actions on cardholders/accounts/, but are limited to acting on cardholders/jobs/accounts/cards within their FI (unless they are assigned to the admin FI) |
next_rotation_on | date | Date of next password rotation for this user. |
created_on | date | Date this site was created on |
last_updated_on | date | Date this site was last updated on |
username | string |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create user
const user = await session.createUser({
"financial_institution_id": 1384278015,
"username": "jsmith123",
"password": "BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=",
"first_name": "Joe",
"last_name": "Smith",
"password_lifetime": 196,
"email": "test_email@strivve.com",
"is_password_update_required": false,
"role": "admin",
"next_rotation_on": "2009-05-30T23:55:01.284Z"
}, CARDHOLDER_SAFE_KEY);
PropertyBag body = new PropertyBag()
{
{ "financial_institution_id", 1384278015 },
{ "username", "jsmith123" },
{ "password", "BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=" },
{ "first_name", "Joe" },
{ "last_name", "Smith" },
{ "password_lifetime", 196 },
{ "email", "test_email@strivve.com" },
{ "is_password_update_required", false },
{ "role", "admin" },
{ "next_rotation_on", "2009-05-30T23:55:01.284Z" }
};
CardSavrResponse<User> user = await http.CreateUserAsync(body, CARDHOLDER_SAFE_KEY);
JsonObject body = Json.createObjectBuilder()
.add("financial_institution_id", 1384278015 )
.add("username", "jsmith123" )
.add("password", "BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=" )
.add("first_name", "Joe" )
.add("last_name", "Smith" )
.add("password_lifetime", 196 )
.add("email", "test_email@strivve.com" )
.add("is_password_update_required", false )
.add("role", "admin" )
.add("next_rotation_on", "2009-05-30T23:55:01.284Z" )
.build();
JsonValue user = session.post("/cardsavr_users", body, null, null);
curl -d "{\"financial_institution_id\":1384278015,\"username\":\"jsmith123\",\"password\":\"BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=\",\"first_name\":\"Joe\",\"last_name\":\"Smith\",\"password_lifetime\":196,\"email\":\"test_email@strivve.com\",\"is_password_update_required\":false,\"role\":\"admin\",\"next_rotation_on\":\"2009-05-30T23:55:01.284Z\"}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_users/
Path
POST /cardsavr_users
Description
Create a user and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
financial_institution_id | number | yes | |
username | string | yes | |
password | string | yes | |
first_name | string | no | |
last_name | string | no | |
password_lifetime | number | no | Length of time that password will remain valid. |
string | no | ||
is_password_update_required | boolean | no | |
role | string enum* | yes | User role (cardholder_agent, cardholder_sso_agent or customer_agent) determines the user's ability to access certain endpoints and perform certain operations within the CardSavr API. cardholder_agents can create cardholders, create card's addresses for those cardholders, create accounts for those cardholders, and post jobs for those cardholders. cardholder_sso_agents are like cardholder_agent, but cannot create cardholder or cards. customer_agents can peform all actions on cardholders/accounts/, but are limited to acting on cardholders/jobs/accounts/cards within their FI (unless they are assigned to the admin FI) |
next_rotation_on | date | no | Date of next password rotation for this user. |
string enum*
- admin
- cardholder_sso_agent
- cardholder_agent
- customer_agent
- swch_agent
Update user
const user = await session.updateUser(1,{
"financial_institution_id": 1942030194,
"first_name": "Joe",
"last_name": "Smith",
"password_lifetime": 181,
"email": "test_email@strivve.com",
"is_password_update_required": false,
"role": "swch_agent",
"next_rotation_on": "2011-10-28T09:04:20.612Z",
"username": "jsmith123",
"password": "BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI="
}, NEW_CARDHODLER_SAFE_KEY, CARDHOLDER_SAFE_KEY);
PropertyBag body = new PropertyBag()
{
{ "financial_institution_id", 1942030194 },
{ "first_name", "Joe" },
{ "last_name", "Smith" },
{ "password_lifetime", 181 },
{ "email", "test_email@strivve.com" },
{ "is_password_update_required", false },
{ "role", "swch_agent" },
{ "next_rotation_on", "2011-10-28T09:04:20.612Z" },
{ "username", "jsmith123" },
{ "password", "BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=" }
};
CardSavrResponse<User> user = await http.UpdateUserAsync(body, NEW_CARDHODLER_SAFE_KEY, CARDHOLDER_SAFE_KEY);
JsonObject body = Json.createObjectBuilder()
.add("financial_institution_id", 1942030194 )
.add("first_name", "Joe" )
.add("last_name", "Smith" )
.add("password_lifetime", 181 )
.add("email", "test_email@strivve.com" )
.add("is_password_update_required", false )
.add("role", "swch_agent" )
.add("next_rotation_on", "2011-10-28T09:04:20.612Z" )
.add("username", "jsmith123" )
.add("password", "BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=" )
.build();
JsonValue user = session.put("/cardsavr_users", body, null, null);
curl -d "{\"financial_institution_id\":1942030194,\"first_name\":\"Joe\",\"last_name\":\"Smith\",\"password_lifetime\":181,\"email\":\"test_email@strivve.com\",\"is_password_update_required\":false,\"role\":\"swch_agent\",\"next_rotation_on\":\"2011-10-28T09:04:20.612Z\",\"username\":\"jsmith123\",\"password\":\"BSN6W6IF72W6EVWwbwgqYIo51ad/ZCZ74vxa3rzyQqI=\"}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-new-cardholder-safe-key: NEW_CARDHODLER_SAFE_KEY"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_users/665640954
Path
PUT /cardsavr_users OR /cardsavr_users/{id}
Description
Update a user and return the updated object. An id is required on every update request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
financial_institution_id | number | |
first_name | string | |
last_name | string | |
password_lifetime | number | Length of time that password will remain valid. |
string | ||
is_password_update_required | boolean | |
role | string enum* | User role (cardholder_agent, cardholder_sso_agent or customer_agent) determines the user's ability to access certain endpoints and perform certain operations within the CardSavr API. cardholder_agents can create cardholders, create card's addresses for those cardholders, create accounts for those cardholders, and post jobs for those cardholders. cardholder_sso_agents are like cardholder_agent, but cannot create cardholder or cards. customer_agents can peform all actions on cardholders/accounts/, but are limited to acting on cardholders/jobs/accounts/cards within their FI (unless they are assigned to the admin FI) |
next_rotation_on | date | Date of next password rotation for this user. |
Delete user
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/cardsavr_users/665640954
await session.deleteUser(undefined);
CardSavrResponse<User> user = await http.DeleteUserAsync(undefined);
JsonValue user = session.delete("/cardsavr_users", undefined, null);
Path
DELETE /cardsavr_users/{id}
Description
Delete a user and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Financial Institutions
Financial Institution (FI) objects represent individual FIs and can be linked to users and cardholders. They also contain the configuration information that can be used to customize an FI's CardUpdatr instance, if one exists.
Get financial institution
const financialinstitutions = await session.getFinancialInstitutions(478801859,{"sort":"id","is_descending":true,"page":1, "page_length":25,);
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<FinancialInstitutions> financialinstitutions = await session.GetFinancialInstitutionsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration =
JsonArray response = (JsonArray)session.get(478801859, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 478801859,
"name": "CIjVcPmwGvIETVCPiWPjaImGToeFaVSIkcJTBxpYkTNnbbuFwJtjMVFcZGJdkXz",
"description": "Qt",
"lookup_key": "mgHatDLVPcTWbBGCKdPqGXGKSpEKVNgswubIPsKxAwSavgpvJXAwWyaESKJUkJL",
"alternate_lookup_key": "YwlBoskcrzOlZbKzvlerIbDnrltbFWMxzPoDXCELsfFnlqSfIBsCcQlcNUcuBXF",
"last_activity": "2017-09-08T00:42:39.675Z",
"created_on": "2010-08-16T23:22:55.352Z",
"last_updated_on": "1971-11-11T01:22:58.886Z"
}
Path
GET /financial_institutions (batch) or GET /financial_institutions/:id (singular)
Description
Returns the financial institution specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable financial institutions, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- id
- names
- lookup_key
- exclude_lookup_keys
- alternate_lookup_key
- last_activity_min / last_activity_max
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/financial_institutions?ids=1,2
Singular GET requests
Singular requests only return the financial institution matching the id provided in the path.
Example GET request path:/financial_institutions/478801859
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this financial institution. |
name | string | |
description | string | |
lookup_key | string | Unique key used to identify financial institution. |
alternate_lookup_key | string | Alternate lookup key; can be used in case of FI name change that does not match original lookup_key, in order to maintain backwards compatibility. |
last_activity | date | Date of last cardholder creation for this financial institution |
created_on | date | Date this financial institution was created on |
last_updated_on | date | Date this financial institution was last updated on |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create financial institution
const financialinstitution = await session.createFinancialInstitution({
"name": "CIjVcPmwGvIETVCPiWPjaImGToeFaVSIkcJTBxpYkTNnbbuFwJtjMVFcZGJdkXz",
"description": "Qt",
"lookup_key": "mgHatDLVPcTWbBGCKdPqGXGKSpEKVNgswubIPsKxAwSavgpvJXAwWyaESKJUkJL",
"alternate_lookup_key": "YwlBoskcrzOlZbKzvlerIbDnrltbFWMxzPoDXCELsfFnlqSfIBsCcQlcNUcuBXF"
});
PropertyBag body = new PropertyBag()
{
{ "name", "CIjVcPmwGvIETVCPiWPjaImGToeFaVSIkcJTBxpYkTNnbbuFwJtjMVFcZGJdkXz" },
{ "description", "Qt" },
{ "lookup_key", "mgHatDLVPcTWbBGCKdPqGXGKSpEKVNgswubIPsKxAwSavgpvJXAwWyaESKJUkJL" },
{ "alternate_lookup_key", "YwlBoskcrzOlZbKzvlerIbDnrltbFWMxzPoDXCELsfFnlqSfIBsCcQlcNUcuBXF" }
};
CardSavrResponse<FinancialInstitution> financialinstitution = await http.CreateFinancialInstitutionAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("name", "CIjVcPmwGvIETVCPiWPjaImGToeFaVSIkcJTBxpYkTNnbbuFwJtjMVFcZGJdkXz" )
.add("description", "Qt" )
.add("lookup_key", "mgHatDLVPcTWbBGCKdPqGXGKSpEKVNgswubIPsKxAwSavgpvJXAwWyaESKJUkJL" )
.add("alternate_lookup_key", "YwlBoskcrzOlZbKzvlerIbDnrltbFWMxzPoDXCELsfFnlqSfIBsCcQlcNUcuBXF" )
.build();
JsonValue financialinstitution = session.post("/financial_institutions", body, null, null);
curl -d "{\"name\":\"CIjVcPmwGvIETVCPiWPjaImGToeFaVSIkcJTBxpYkTNnbbuFwJtjMVFcZGJdkXz\",\"description\":\"Qt\",\"lookup_key\":\"mgHatDLVPcTWbBGCKdPqGXGKSpEKVNgswubIPsKxAwSavgpvJXAwWyaESKJUkJL\",\"alternate_lookup_key\":\"YwlBoskcrzOlZbKzvlerIbDnrltbFWMxzPoDXCELsfFnlqSfIBsCcQlcNUcuBXF\"}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/financial_institutions/
Path
POST /financial_institutions
Description
Create a financial institution and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
name | string | yes | |
description | string | no | |
lookup_key | string | yes | Unique key used to identify financial institution. |
alternate_lookup_key | string | no | Alternate lookup key; can be used in case of FI name change that does not match original lookup_key, in order to maintain backwards compatibility. |
See financial institution response attributes.
Update financial institution
const financialinstitution = await session.updateFinancialInstitution(1,{
"name": "UTjymsymJJhLjrRdiONwGYpxpbvPQSOzqArZqdAFbymQFdUnQhBFJCNXxTpKfHS",
"description": "CYgeLoWQURGfZNMXuEKrNhWAc",
"lookup_key": "OjcTjTqcVqKMyKtcUcSxvgsKNLBqxXsLVlTvVaYBgqYWVrgmbeZZNaPGhqUuSoZ",
"alternate_lookup_key": "uJyxtvVSaUyLAULDemdfRqQvbIUHHUdstygCFiZIQvnDLmKLazgXHbQUFoRTNSD"
});
PropertyBag body = new PropertyBag()
{
{ "name", "UTjymsymJJhLjrRdiONwGYpxpbvPQSOzqArZqdAFbymQFdUnQhBFJCNXxTpKfHS" },
{ "description", "CYgeLoWQURGfZNMXuEKrNhWAc" },
{ "lookup_key", "OjcTjTqcVqKMyKtcUcSxvgsKNLBqxXsLVlTvVaYBgqYWVrgmbeZZNaPGhqUuSoZ" },
{ "alternate_lookup_key", "uJyxtvVSaUyLAULDemdfRqQvbIUHHUdstygCFiZIQvnDLmKLazgXHbQUFoRTNSD" }
};
CardSavrResponse<FinancialInstitution> financialinstitution = await http.UpdateFinancialInstitutionAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("name", "UTjymsymJJhLjrRdiONwGYpxpbvPQSOzqArZqdAFbymQFdUnQhBFJCNXxTpKfHS" )
.add("description", "CYgeLoWQURGfZNMXuEKrNhWAc" )
.add("lookup_key", "OjcTjTqcVqKMyKtcUcSxvgsKNLBqxXsLVlTvVaYBgqYWVrgmbeZZNaPGhqUuSoZ" )
.add("alternate_lookup_key", "uJyxtvVSaUyLAULDemdfRqQvbIUHHUdstygCFiZIQvnDLmKLazgXHbQUFoRTNSD" )
.build();
JsonValue financialinstitution = session.put("/financial_institutions", body, null, null);
curl -d "{\"name\":\"UTjymsymJJhLjrRdiONwGYpxpbvPQSOzqArZqdAFbymQFdUnQhBFJCNXxTpKfHS\",\"description\":\"CYgeLoWQURGfZNMXuEKrNhWAc\",\"lookup_key\":\"OjcTjTqcVqKMyKtcUcSxvgsKNLBqxXsLVlTvVaYBgqYWVrgmbeZZNaPGhqUuSoZ\",\"alternate_lookup_key\":\"uJyxtvVSaUyLAULDemdfRqQvbIUHHUdstygCFiZIQvnDLmKLazgXHbQUFoRTNSD\"}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/financial_institutions/478801859
Path
PUT /financial_institutions OR /financial_institutions/{id}
Description
Update a financial institution and return the updated object. An id is required on every update request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
name | string | |
description | string | |
lookup_key | string | Unique key used to identify financial institution. |
alternate_lookup_key | string | Alternate lookup key; can be used in case of FI name change that does not match original lookup_key, in order to maintain backwards compatibility. |
See financial institution response parameters.
Delete financial institution
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/financial_institutions/478801859
await session.deleteFinancialInstitution(undefined);
CardSavrResponse<FinancialInstitution> financialinstitution = await http.DeleteFinancialInstitutionAsync(undefined);
JsonValue financialinstitution = session.delete("/financial_institutions", undefined, null);
Path
DELETE /financial_institutions/{id}
Description
Delete a financial institution and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
See financial institution response parameters.
Integrators
Integrators are applications that integrate the CardSavr API, using their own unique integrator key. An integrator name and key are required for all calls to the CardSavr API. An integrator can be associated with multiple users.
Get integrator
const integrators = await session.getIntegrators(1444857493,{"sort":"id","is_descending":true,"page":1, "page_length":25,);
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<Integrators> integrators = await session.GetIntegratorsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration =
JsonArray response = (JsonArray)session.get(1444857493, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 1444857493,
"name": "RfJovShRQCFbAtutAwpCFakaOmAyZGSdVZbsEQMCQosvzrIYM",
"description": "BEcHAOzb",
"current_key": "LStjUequR3lMTR/ua4eBhTXpjZvpRx04NeAOBn5hVGc=",
"key_lifetime": 328,
"next_rotation_on": "2015-03-18T21:54:25.369Z",
"created_on": "1980-11-04T17:02:49.911Z",
"last_updated_on": "2001-06-14T22:33:55.568Z"
}
Path
GET /integrators (batch) or GET /integrators/:id (singular)
Description
Returns the integrator specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable integrators, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- names
- name
- next_rotation_on_min / next_rotation_on_max
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/integrators?ids=1,2
Singular GET requests
Singular requests only return the integrator matching the id provided in the path.
Example GET request path:/integrators/1444857493
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this integrator. |
name | string | Name of integrator. |
description | string | |
current_key | string | Current key for this integrator. |
key_lifetime | number | Sets the duration of validity for integrator key. |
next_rotation_on | date | Date of next key rotation for this integrator. |
created_on | date | Date this integrator was created on |
last_updated_on | date | Date this integrator was last updated on |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create integrator
const integrator = await session.createIntegrator({
"name": "RfJovShRQCFbAtutAwpCFakaOmAyZGSdVZbsEQMCQosvzrIYM",
"description": "BEcHAOzb",
"current_key": "LStjUequR3lMTR/ua4eBhTXpjZvpRx04NeAOBn5hVGc=",
"key_lifetime": 328,
"next_rotation_on": "2015-03-18T21:54:25.369Z"
});
PropertyBag body = new PropertyBag()
{
{ "name", "RfJovShRQCFbAtutAwpCFakaOmAyZGSdVZbsEQMCQosvzrIYM" },
{ "description", "BEcHAOzb" },
{ "current_key", "LStjUequR3lMTR/ua4eBhTXpjZvpRx04NeAOBn5hVGc=" },
{ "key_lifetime", 328 },
{ "next_rotation_on", "2015-03-18T21:54:25.369Z" }
};
CardSavrResponse<Integrator> integrator = await http.CreateIntegratorAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("name", "RfJovShRQCFbAtutAwpCFakaOmAyZGSdVZbsEQMCQosvzrIYM" )
.add("description", "BEcHAOzb" )
.add("current_key", "LStjUequR3lMTR/ua4eBhTXpjZvpRx04NeAOBn5hVGc=" )
.add("key_lifetime", 328 )
.add("next_rotation_on", "2015-03-18T21:54:25.369Z" )
.build();
JsonValue integrator = session.post("/integrators", body, null, null);
curl -d "{\"name\":\"RfJovShRQCFbAtutAwpCFakaOmAyZGSdVZbsEQMCQosvzrIYM\",\"description\":\"BEcHAOzb\",\"current_key\":\"LStjUequR3lMTR/ua4eBhTXpjZvpRx04NeAOBn5hVGc=\",\"key_lifetime\":328,\"next_rotation_on\":\"2015-03-18T21:54:25.369Z\"}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/integrators/
Path
POST /integrators
Description
Create a integrator and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
name | string | yes | Name of integrator. |
description | string | no | |
current_key | string | yes | Current key for this integrator. |
key_lifetime | number | no | Sets the duration of validity for integrator key. |
next_rotation_on | date | no | Date of next key rotation for this integrator. |
See integrator response attributes.
Update integrator
const integrator = await session.updateIntegrator(1,{
"name": "xnakbfIwBwnwuZrkXylxzNyqDSbMsVbHOepJicHSWHdcSCoLY",
"description": "JhjViCCORA",
"current_key": "+M6WEu0Zrsb0fuNADYjfX9ZlKMIGfPmBAWgiEUrVBVQ=",
"key_lifetime": 15,
"next_rotation_on": "1981-03-10T18:10:54.691Z"
});
PropertyBag body = new PropertyBag()
{
{ "name", "xnakbfIwBwnwuZrkXylxzNyqDSbMsVbHOepJicHSWHdcSCoLY" },
{ "description", "JhjViCCORA" },
{ "current_key", "+M6WEu0Zrsb0fuNADYjfX9ZlKMIGfPmBAWgiEUrVBVQ=" },
{ "key_lifetime", 15 },
{ "next_rotation_on", "1981-03-10T18:10:54.691Z" }
};
CardSavrResponse<Integrator> integrator = await http.UpdateIntegratorAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("name", "xnakbfIwBwnwuZrkXylxzNyqDSbMsVbHOepJicHSWHdcSCoLY" )
.add("description", "JhjViCCORA" )
.add("current_key", "+M6WEu0Zrsb0fuNADYjfX9ZlKMIGfPmBAWgiEUrVBVQ=" )
.add("key_lifetime", 15 )
.add("next_rotation_on", "1981-03-10T18:10:54.691Z" )
.build();
JsonValue integrator = session.put("/integrators", body, null, null);
curl -d "{\"name\":\"xnakbfIwBwnwuZrkXylxzNyqDSbMsVbHOepJicHSWHdcSCoLY\",\"description\":\"JhjViCCORA\",\"current_key\":\"+M6WEu0Zrsb0fuNADYjfX9ZlKMIGfPmBAWgiEUrVBVQ=\",\"key_lifetime\":15,\"next_rotation_on\":\"1981-03-10T18:10:54.691Z\"}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/integrators/1444857493
Path
PUT /integrators OR /integrators/{id}
Description
Update a integrator and return the updated object. An id is required on every update request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
name | string | Name of integrator. |
description | string | |
current_key | string | Current key for this integrator. |
key_lifetime | number | Sets the duration of validity for integrator key. |
next_rotation_on | date | Date of next key rotation for this integrator. |
See integrator response parameters.
Delete integrator
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/integrators/1444857493
await session.deleteIntegrator(undefined);
CardSavrResponse<Integrator> integrator = await http.DeleteIntegratorAsync(undefined);
JsonValue integrator = session.delete("/integrators", undefined, null);
Path
DELETE /integrators/{id}
Description
Delete a integrator and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
See integrator response parameters.
Merchant sites
A merchant site object contains information, such as images URLs and hostname, for a CardSavr-supported merchant site.
Get merchant site
const merchantsites = await session.getMerchantSites(421751717,{"sort":"id","is_descending":true,"page":1, "page_length":25,);
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<MerchantSites> merchantsites = await session.GetMerchantSitesAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration =
JsonArray response = (JsonArray)session.get(421751717, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 421751717,
"name": "Amazon",
"note": "YtsnMAIpPzsPXwrbEAMMUww",
"host": "amazon.com",
"tags": [
"Lc5e%/]x",
37,
"!"
],
"interface_type": "rpa",
"job_type": "CARD_PLACEMENT",
"required_form_fields": [
"email",
"phone_number",
"card_data",
"cvv",
"billing_address",
"postal_code"
],
"images": [
{
"url": "https://d1t7g1oas7m24a.cloudfront.net/tiles/dollarshaveclub.com?width=128&version=21f917315911eec1b1705bc7784ce861579cff2b",
"width": 128,
"grayscale": false
},
{
"url": "https://d1t7g1oas7m24a.cloudfront.net/tiles/dollarshaveclub.com?width=32&version=21f917315911eec1b1705bc7784ce861579cff2b",
"width": 32,
"grayscale": false
}
],
"account_link": [
{
"key_name": "username",
"label": "Username",
"type": "initial_account_link"
},
{
"key_name": "password",
"label": "Password",
"type": "initial_account_link",
"secret": true
},
{
"key_name": "otp",
"label": "One Time Passcode",
"type": ""
}
],
"messages": {
"mfa_label": "Additional information required, this code may be sent to your phone or email address.",
"additional_info_message": "",
"auth_message": "Linking account."
},
"script_directory": "cjvj",
"record_final_site_artifacts": true,
"puppeteer_screenshot": false,
"login_page": "https://www.merchantsite.com/login",
"forgot_password_page": "https://www.merchantsite.com/forgot_password",
"credit_card_page": "https://www.merchantsite.com/credit_card",
"wallet_page": "UhElrZNIWZayhSvx",
"merchant_sso_group": "IIKQwXNUklUgcxMzyk",
"tier": 1145990086,
"cookie_caching_scheme": "none",
"dynamic_viewport": true,
"use_puppeteer": true
}
Path
GET /merchant_sites (batch) or GET /merchant_sites/:id (singular)
Description
Returns the merchant site specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable merchant sites, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- id
- exclude_ids
- top_ids
- name_starts_with
- hosts
- host
- exclude_hosts
- top_hosts
- host_starts_with
- tags
- image_widths
Example batch GET request path:/merchant_sites?ids=1,2
Singular GET requests
Singular requests only return the merchant site matching the id provided in the path.
Example GET request path:/merchant_sites/421751717
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this merchant site. |
name | string | |
note | string | Human-readable note about the site for developers |
host | string | For interface type 'dcs', hostname of the DCS broker server for the merchant site; for interface type 'vbs' hostname of the merchant_site. e.g. amazon.com |
tags | array | Tags for filtering desired merchant sites. This could either be site status (e.g. prod, down), countries supported (e.g. usa, canada), or site attributes (e.g. synthetic). Tags can also be compounded to create combinations: (e.g. ?tags=prod,synthetic&tags=usa,synthetic means all sites tagged prod and usa and also sites tagged synthetic) |
interface_type | string | Type of interface agent to use with merchant. Set to 'dcs' for a site that has direct connect support; and to 'vbs' for a site using Robotic Process Automation |
job_type | string | Type of job this site supports. Card placement or bill payment |
required_form_fields | array | Indicates the cardholder personal information fields that are required by this site. |
images | array | URLs of the images for this merchant site. Use a filter parameter of 'image_widths', a comma delimited list of widths (e.g. image_widths=64). Tile images with these widths will be returned. The default is 128 and 32 width images. |
account_link | array | One or more property sets with key names to populated on POST/PUT /cardsavr_accounts requests, and labels to display to the end user for the type of information being requested for this site ( e.g. Username, Password, Account Number, Email, ... ) Each property contains its 'key_name', a 'label' that defines the property, a 'secret' flag (property should be masked on input like a password), and a type. Only properties with a type of 'initial_account_link' should be presented upon initial credential collection. For example, an input field for 'tfa' is not displayed on initial collection. All other non-'initial_account_link' properties will be requested while the transactiion progresses and they are only listed here for informational purposes. |
messages | object | Message properties to display to end users. Supercedes the deprecated loging properties. The message properties are mfa_label: additional informaton required for mfs challenges such as a code sent to users phone or email, additional_info_message: some contextual info sent from CardSavr to aid the user interaction, auth_message: a label to display during during the authentication phase |
script_directory | string | Optional override for the name of the directory to lookup scripts in (default is host) |
record_final_site_artifacts | boolean | Take a snapshot of html and a screenshot of the final merchant site. Disabling this can speed up task cleanup. |
puppeteer_screenshot | boolean | Use puppeteer to take a screenshot of site for debugging. |
login_page | string | URL of login page. |
forgot_password_page | string | Merchant's forgotten password page. |
credit_card_page | string | Merchant's credit card entry page. |
wallet_page | string | URL of the site's wallet page, where the is a list of last 4 card numbers. |
merchant_sso_group | string | Default group a site rolls up to. Jobs for the same user account should not run simultaneously. |
tier | number | Site's tier based on perceived card usage on that site. |
cookie_caching_scheme | string | Caching scheme for saving site cookies to allow for auto-resumption of previous cardholder sessions |
dynamic_viewport | boolean | whether or not the VBS puppeteer viewport size is dynamic. |
use_puppeteer | boolean | whether or not the VBS will use puppeteer instead of playwright. |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Notifications
Notification objects define a set of actions to be triggered by certain CardSavr events, such as session completion.
Get notification
const notifications = await session.getNotifications(1811795793,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["financial_institution"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<Notifications> notifications = await session.GetNotificationsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["financial_institution"])}
JsonArray response = (JsonArray)session.get(1811795793, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 1811795793,
"name": "Sample Notification",
"type": "webhook",
"event": "webhook_error_summary",
"config": {
"recipient": "cardholder",
"url": null,
"from_email": "CardUpdatr <no-reply@cardupdatr.app>",
"return_path": "no-reply@cardupdatr.app",
"send_email_time": null,
"interval_length": null,
"interval_type": null
},
"html_template": "CddiNoOBELIQdyv",
"text_template": "EInPepGTzvNTzajdUKePbNwdurIXM",
"created_on": "2023-05-22T14:53:36.214Z",
"last_updated_on": "2002-08-25T00:53:09.939Z",
"financial_institution": {
"id": 61599913,
"name": "FDmwvHzEyhNFHkNrxtTWXHyegakvMTTgCcPZtCPCBwbtPCLAOnAkbTabzNIXUCt",
"description": "sobY",
"lookup_key": "RgdbpdRHjrXZwfItzDDCsYBQjtnBJtcXNqxLbQxbqDBvbeqfvXZvcejPzEitByf",
"alternate_lookup_key": "CfpKYKAyYQhprCjggVvPMXDdofJSLehPxbgCryfNVCTUeTZbcRsQaQpyBdSqblW",
"last_activity": "1980-11-13T02:28:33.564Z",
"created_on": "2017-12-04T12:42:42.099Z",
"last_updated_on": "1995-11-10T13:13:29.402Z"
}
}
Path
GET /notifications (batch) or GET /notifications/:id (singular)
Description
Returns the notification specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable notifications, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- financial_institution_ids
- names
- type
- events
- event
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/notifications?ids=1,2
Singular GET requests
Singular requests only return the notification matching the id provided in the path.
Example GET request path:/notifications/1811795793
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this notification. |
name | string | Name of this notification. |
type | string | Notification type (e.g. webhook or email). |
event | string | Event that will triger the notification (e.g. session complete). |
config | object | |
html_template | string | Overrides the default CardUpdatr html email template (for email notifications). |
text_template | string | Overrides the default CardUpdatr text email template (for email notifications). |
created_on | date | Date this notification was created on |
last_updated_on | date | Date this notification was last updated on |
financial_institution_id | number (fk) financial institutions | ID of the financial institution associated with this notification. |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create notification
const notification = await session.createNotification({
"financial_institution_id": 780479503,
"name": "Sample Notification",
"type": "webhook",
"event": "webhook_error_summary",
"config": {
"recipient": "cardholder",
"url": null,
"from_email": "CardUpdatr <no-reply@cardupdatr.app>",
"return_path": "no-reply@cardupdatr.app",
"send_email_time": null,
"interval_length": null,
"interval_type": null
},
"html_template": "CddiNoOBELIQdyv",
"text_template": "EInPepGTzvNTzajdUKePbNwdurIXM"
});
PropertyBag body = new PropertyBag()
{
{ "financial_institution_id", 780479503 },
{ "name", "Sample Notification" },
{ "type", "webhook" },
{ "event", "webhook_error_summary" },
{ "html_template", "CddiNoOBELIQdyv" },
{ "text_template", "EInPepGTzvNTzajdUKePbNwdurIXM" }
};
CardSavrResponse<Notification> notification = await http.CreateNotificationAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("financial_institution_id", 780479503 )
.add("name", "Sample Notification" )
.add("type", "webhook" )
.add("event", "webhook_error_summary" )
.add("html_template", "CddiNoOBELIQdyv" )
.add("text_template", "EInPepGTzvNTzajdUKePbNwdurIXM" )
.build();
JsonValue notification = session.post("/notifications", body, null, null);
curl -d "{\"financial_institution_id\":780479503,\"name\":\"Sample Notification\",\"type\":\"webhook\",\"event\":\"webhook_error_summary\",\"config\":{\"recipient\":\"cardholder\",\"url\":null,\"from_email\":\"CardUpdatr <no-reply@cardupdatr.app>\",\"return_path\":\"no-reply@cardupdatr.app\",\"send_email_time\":null,\"interval_length\":null,\"interval_type\":null},\"html_template\":\"CddiNoOBELIQdyv\",\"text_template\":\"EInPepGTzvNTzajdUKePbNwdurIXM\"}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/notifications/
Path
POST /notifications
Description
Create a notification and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
financial_institution_id | number | yes | ID of the financial institution associated with this notification. |
name | string | yes | Name of this notification. |
type | string enum* | yes | Notification type (e.g. webhook or email). |
event | string enum** | yes | Event that will triger the notification (e.g. session complete). |
config | object | no | |
html_template | string | no | Overrides the default CardUpdatr html email template (for email notifications). |
text_template | string | no | Overrides the default CardUpdatr text email template (for email notifications). |
See notification response attributes.
string enum*
- webhook
string enum**
- session_complete
- webhook_error_summary
- merchant_site_updates_top
- merchant_site_updates_all
Update notification
const notification = await session.updateNotification(1,{
"name": "Sample Notification",
"type": "email",
"event": "merchant_site_updates_top",
"config": {
"recipient": "cardholder",
"url": null,
"from_email": "CardUpdatr <no-reply@cardupdatr.app>",
"return_path": "no-reply@cardupdatr.app",
"send_email_time": null,
"interval_length": null,
"interval_type": null
},
"html_template": "cyrChzIdjwscFdsVi",
"text_template": "yyeUQOgFFgLmWffjuYCPbjvCdciEvOK"
});
PropertyBag body = new PropertyBag()
{
{ "name", "Sample Notification" },
{ "type", "email" },
{ "event", "merchant_site_updates_top" },
{ "html_template", "cyrChzIdjwscFdsVi" },
{ "text_template", "yyeUQOgFFgLmWffjuYCPbjvCdciEvOK" }
};
CardSavrResponse<Notification> notification = await http.UpdateNotificationAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("name", "Sample Notification" )
.add("type", "email" )
.add("event", "merchant_site_updates_top" )
.add("html_template", "cyrChzIdjwscFdsVi" )
.add("text_template", "yyeUQOgFFgLmWffjuYCPbjvCdciEvOK" )
.build();
JsonValue notification = session.put("/notifications", body, null, null);
curl -d "{\"name\":\"Sample Notification\",\"type\":\"email\",\"event\":\"merchant_site_updates_top\",\"config\":{\"recipient\":\"cardholder\",\"url\":null,\"from_email\":\"CardUpdatr <no-reply@cardupdatr.app>\",\"return_path\":\"no-reply@cardupdatr.app\",\"send_email_time\":null,\"interval_length\":null,\"interval_type\":null},\"html_template\":\"cyrChzIdjwscFdsVi\",\"text_template\":\"yyeUQOgFFgLmWffjuYCPbjvCdciEvOK\"}"
-X PUT -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/notifications/1811795793
Path
PUT /notifications OR /notifications/{id}
Description
Update a notification and return the updated object. An id is required on every update request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
name | string | Name of this notification. |
type | string enum* | Notification type (e.g. webhook or email). |
event | string enum** | Event that will triger the notification (e.g. session complete). |
config | object | |
html_template | string | Overrides the default CardUpdatr html email template (for email notifications). |
text_template | string | Overrides the default CardUpdatr text email template (for email notifications). |
See notification response parameters.
Delete notification
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/notifications/1811795793
await session.deleteNotification(undefined);
CardSavrResponse<Notification> notification = await http.DeleteNotificationAsync(undefined);
JsonValue notification = session.delete("/notifications", undefined, null);
Path
DELETE /notifications/{id}
Description
Delete a notification and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
See notification response parameters.
Notification results
Notification result objects are records of an attempt/attempts to send a notification, indicating success/failure and additional relevant information.
Get notification result
const notificationresults = await session.getNotificationResults(1338807535,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["notification"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<NotificationResults> notificationresults = await session.GetNotificationResultsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["notification"])}
JsonArray response = (JsonArray)session.get(1338807535, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 1338807535,
"last_attempt_date": "2008-04-14T15:12:22.777Z",
"fi_lookup_key": "DplOklhSgzCqxfiWBhFMSfTlJnlbnOOFqgjnQzTNnbFHtrhRUBWNtlmxfrWPRcV",
"cuid": "HgDugQBfGzTgtZqnIHbDaVewMSzlm",
"status": "success",
"attempts": 1980200462,
"notification_data": {
"TXMJccGzYUtf": "H[okVi7u%q4fy.H(_VZ0.KTwVV",
"xlRGLoLMIrBT": 43,
"gGVivAPljZtF": false
},
"created_on": "1987-11-20T09:26:44.920Z",
"last_updated_on": "2014-10-02T23:13:17.440Z",
"notification": {
"id": 1069490097,
"name": "Sample Notification",
"type": "webhook",
"event": "session_complete",
"config": {
"recipient": "cardholder",
"url": null,
"from_email": "CardUpdatr <no-reply@cardupdatr.app>",
"return_path": "no-reply@cardupdatr.app",
"send_email_time": null,
"interval_length": null,
"interval_type": null
},
"html_template": "y",
"text_template": "q",
"created_on": "1977-02-05T04:06:11.422Z",
"last_updated_on": "1987-08-01T14:35:13.802Z"
}
}
Path
GET /notification_results (batch) or GET /notification_results/:id (singular)
Description
Returns the notification result specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable notification results, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- notification_ids
- last_attempt_date_min / last_attempt_date_max
- fi_lookup_keys
- cuid
- status
- attempts
- attempts_min / attempts_max
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/notification_results?ids=1,2
Singular GET requests
Singular requests only return the notification result matching the id provided in the path.
Example GET request path:/notification_results/1338807535
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this notification. |
last_attempt_date | date | Date of last attempt to post this notification. |
fi_lookup_key | string | FI lookup key associated with the attempted notification. |
cuid | string | External unique ID for cardholder--can be account_id, email address, phone number, etc. A random number will be gnenerated if not provided. |
status | string | Status of the notification attempt. |
attempts | number | Number of attempts made to send or post notification. |
notification_data | object | Data sent with the notification. |
created_on | date | Date this notification result was created on |
last_updated_on | date | Date this notification result was last updated on |
notification_id | number (fk) notifications | ID of the attempted notification. |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create notification result
const notificationresult = await session.createNotificationResult({
"notification_id": 800158275,
"fi_lookup_key": "DplOklhSgzCqxfiWBhFMSfTlJnlbnOOFqgjnQzTNnbFHtrhRUBWNtlmxfrWPRcV",
"cuid": "HgDugQBfGzTgtZqnIHbDaVewMSzlm",
"status": "success",
"attempts": 1980200462,
"notification_data": {
"TXMJccGzYUtf": "H[okVi7u%q4fy.H(_VZ0.KTwVV",
"xlRGLoLMIrBT": 43,
"gGVivAPljZtF": false
}
});
PropertyBag body = new PropertyBag()
{
{ "notification_id", 800158275 },
{ "fi_lookup_key", "DplOklhSgzCqxfiWBhFMSfTlJnlbnOOFqgjnQzTNnbFHtrhRUBWNtlmxfrWPRcV" },
{ "cuid", "HgDugQBfGzTgtZqnIHbDaVewMSzlm" },
{ "status", "success" },
{ "attempts", 1980200462 }
};
CardSavrResponse<NotificationResult> notificationresult = await http.CreateNotificationResultAsync(body);
JsonObject body = Json.createObjectBuilder()
.add("notification_id", 800158275 )
.add("fi_lookup_key", "DplOklhSgzCqxfiWBhFMSfTlJnlbnOOFqgjnQzTNnbFHtrhRUBWNtlmxfrWPRcV" )
.add("cuid", "HgDugQBfGzTgtZqnIHbDaVewMSzlm" )
.add("status", "success" )
.add("attempts", 1980200462 )
.build();
JsonValue notificationresult = session.post("/notification_results", body, null, null);
curl -d "{\"notification_id\":800158275,\"fi_lookup_key\":\"DplOklhSgzCqxfiWBhFMSfTlJnlbnOOFqgjnQzTNnbFHtrhRUBWNtlmxfrWPRcV\",\"cuid\":\"HgDugQBfGzTgtZqnIHbDaVewMSzlm\",\"status\":\"success\",\"attempts\":1980200462,\"notification_data\":{\"TXMJccGzYUtf\":\"H[okVi7u%q4fy.H(_VZ0.KTwVV\",\"xlRGLoLMIrBT\":43,\"gGVivAPljZtF\":false}}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/notification_results/
Path
POST /notification_results
Description
Create a notification result and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
notification_id | number | yes | ID of the attempted notification. |
fi_lookup_key | string | yes | FI lookup key associated with the attempted notification. |
cuid | string | yes | External unique ID for cardholder--can be account_id, email address, phone number, etc. A random number will be gnenerated if not provided. |
status | string enum* | yes | Status of the notification attempt. |
attempts | number | yes | Number of attempts made to send or post notification. |
notification_data | object | no | Data sent with the notification. |
See notification result response attributes.
string enum*
- success
- failure
Single-site jobs
Single-site job objects contain the information necessary to place a payment card on a merchant site, as well as status information about the card placement attempt. They are linked to a single cardholder, account, card, and merchant site.
Get single-site job
const singlesitejobs = await session.getSingleSiteJobs(750836597,{"sort":"id","is_descending":true,"page":1, "page_length":25,{'x-cardsavr-hydration':JSON.stringify(["cardholder","cardsavr_card","cardsavr_account","credential_requests"])});
Paging paging = new Paging() { PageLength = 100, IsDescending = true, Page = 1, Sort = "id" };
HttpRequestHeaders headers = new HttpRequestMessage().Headers;
string[] array = { "cardholder","merchant_site","cardsavr_card" };
var json = JsonConvert.SerializeObject(array);
headers.Add("x-cardsavr-hydration", json);
var query = new {ids = 1};
QueryDef qd = new QueryDef(query);
CardSavrResponse<SingleSiteJobs> singlesitejobs = await session.GetSingleSiteJobsAsync(qd,paging,headers);
Headers headers = session.createHeaders();
headers.paging = Json.createObjectBuilder().add("page", 1).add("page_length", 5).add("is_descending", true).add("sort", "id").build();
headers.hydration = {'x-cardsavr-hydration':JSON.stringify(["cardholder","cardsavr_card","cardsavr_account","credential_requests"])}
JsonArray response = (JsonArray)session.get(750836597, null, headers);
Sample response - not all properties are available to all roles (200 OK):
{
"id": 750836597,
"status": "CANCELLED",
"status_message": "LosqYmvFSUiAPXv",
"termination_type": "USER_DATA_FAILURE",
"custom_data": {
"JMlLIhHrMqOl": "Grc7r(TKWRuTX0qgm7Vc",
"XmyODUFRqdVz": 80,
"ecPtHWTuRFXn": false
},
"notification_sent": false,
"time_elapsed": 488741644,
"auth_percent_complete": 56642461,
"percent_complete": 818184615,
"started_on": "1981-12-19T21:43:37.659Z",
"completed_on": "1992-08-02T10:50:19.487Z",
"created_on": "1986-01-03T06:05:45.953Z",
"last_updated_on": "1977-12-06T12:40:38.326Z",
"use_puppeteer": true,
"cardholder": {
"id": 1848500081,
"type": "ephemeral",
"first_name": "Jane",
"last_name": "Smith",
"email": "test_email@strivve.com",
"meta_key": "l",
"webhook_url": "https://mywebhooks.com/this",
"custom_data": {
"dyfdQaScWHMT": "bpF5decCah@%d94#(EOT6~Rv+IqG",
"moTebbPWfWDU": 18,
"PHHVtBwSmFDR": true
},
"created_on": "1981-11-22T07:19:32.232Z",
"last_updated_on": "1986-11-26T19:45:38.740Z",
"cuid": "omOrvilk"
},
"cardsavr_card": {
"id": 1176505801,
"type": "American Express",
"expiration_month": 12,
"expiration_year": 24,
"name_on_card": "Jane Smith",
"nickname": "Jane's VISA",
"custom_data": {
"PsNoXknreypo": "4rOeMclf8[jKw_(KTFAi90/{",
"gkKvCqhyguAV": 48,
"IRyCNJUefYQG": false
},
"created_on": "1981-10-05T11:42:15.699Z",
"last_updated_on": "2004-09-25T18:53:06.257Z",
"par": "UPToHiruBRRqFENFhtNlooJBkQQRh",
"customer_key": "CWSWHENzRgmIVbefL"
},
"cardsavr_account": {
"id": 380331212,
"last_password_update": "1985-10-06T17:15:33.484Z",
"last_saved_card": "1990-12-06T13:00:27.897Z",
"created_on": "2011-11-25T13:13:55.892Z",
"last_updated_on": "2021-05-16T11:19:39.770Z",
"customer_key": "AtFnWeUKKMxmOVsOIdlJleoWU"
},
"credential_timeout": 272570080
}
Path
GET /place_card_on_single_site_jobs (batch) or GET /place_card_on_single_site_jobs/:id (singular)
Description
Returns the single-site job specified by the provided ID
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Batch GET requests
Batch requests return the first page of all viewable single-site jobs, filtered by any query filters (see list of possible parameters below) listed in the path.
Filter parameters
- ids / id (in path)
- cardholder_ids
- card_ids
- account_ids
- status
- status_include / status_exclude
- termination_type
- termination_types_include / termination_types_exclude
- notification_sent
- time_elapsed_min / time_elapsed_max
- started_on_min / started_on_max
- completed_on_min / completed_on_max
- created_on_min / created_on_max
- last_updated_on_min / last_updated_on_max
Example batch GET request path:/place_card_on_single_site_jobs?ids=1,2
Singular GET requests
Singular requests only return the single-site job matching the id provided in the path.
Example GET request path:/place_card_on_single_site_jobs/750836597
To hydrate all credential requests currently associated with a job, include credential_requests in the hydration header (see example at right).`
Response attributes
Attribute | Type | Description |
---|---|---|
id | number (pk) | Unique ID of this job. |
card_id | number (fk) cards | ID of card associated with this job. |
status | string | Current status of job (e.g. pending_tfa). These names are dynamic and change frequently, so it is best to use status_message to communicate with cardholders. |
status_message | string | Human readable representation of the job's status. |
termination_type | string | Final termination status of a job. (BILLABLE, SITE_INTERACTION_FAILURE, USER_DATA_FAILURE, PROCESS FAILURE) |
custom_data | object | |
notification_sent | boolean | Indicates if a notification has been sent or posted for this job. |
time_elapsed | number | Amount of time elapsed since the creation of the job. |
auth_percent_complete | number | |
percent_complete | number | |
started_on | date | Time when job started. |
completed_on | date | Timestamp of job completion. |
created_on | date | Date this site was created on |
last_updated_on | date | Date this site was last updated on |
use_puppeteer | boolean | whether or not the VBS will use puppeteer instead of playwright. |
cardholder_id | number (fk) cardholders | ID of cardholder associated with this job. |
account_id | number (fk) accounts | ID of account associated with this job. |
credential_timeout | number | Credential timeout value in seconds. |
NOTE: All foreign key parameters (fk) can be hydrated and support cascading delete.
Create single-site job
const singlesitejob = await session.createSingleSiteJob({
"cardholder_id": 1303525921,
"card_id": 503984253,
"account_id": 480054694,
"status": "CANCELLED",
"custom_data": {
"JMlLIhHrMqOl": "Grc7r(TKWRuTX0qgm7Vc",
"XmyODUFRqdVz": 80,
"ecPtHWTuRFXn": false
},
"notification_sent": false,
"time_elapsed": 488741644,
"credential_timeout": 272570080,
"auth_percent_complete": 56642461,
"percent_complete": 818184615,
"started_on": "1981-12-19T21:43:37.659Z",
"completed_on": "1992-08-02T10:50:19.487Z",
"use_puppeteer": true
}, CARDHOLDER_SAFE_KEY);
PropertyBag body = new PropertyBag()
{
{ "cardholder_id", 1303525921 },
{ "card_id", 503984253 },
{ "account_id", 480054694 },
{ "status", "CANCELLED" },
{ "notification_sent", false },
{ "time_elapsed", 488741644 },
{ "credential_timeout", 272570080 },
{ "auth_percent_complete", 56642461 },
{ "percent_complete", 818184615 },
{ "started_on", "1981-12-19T21:43:37.659Z" },
{ "completed_on", "1992-08-02T10:50:19.487Z" },
{ "use_puppeteer", true }
};
CardSavrResponse<SingleSiteJob> singlesitejob = await http.CreateSingleSiteJobAsync(body, CARDHOLDER_SAFE_KEY);
JsonObject body = Json.createObjectBuilder()
.add("cardholder_id", 1303525921 )
.add("card_id", 503984253 )
.add("account_id", 480054694 )
.add("status", "CANCELLED" )
.add("notification_sent", false )
.add("time_elapsed", 488741644 )
.add("credential_timeout", 272570080 )
.add("auth_percent_complete", 56642461 )
.add("percent_complete", 818184615 )
.add("started_on", "1981-12-19T21:43:37.659Z" )
.add("completed_on", "1992-08-02T10:50:19.487Z" )
.add("use_puppeteer", true )
.build();
JsonValue singlesitejob = session.post("/place_card_on_single_site_jobs", body, null, null);
curl -d "{\"cardholder_id\":1303525921,\"card_id\":503984253,\"account_id\":480054694,\"status\":\"CANCELLED\",\"custom_data\":{\"JMlLIhHrMqOl\":\"Grc7r(TKWRuTX0qgm7Vc\",\"XmyODUFRqdVz\":80,\"ecPtHWTuRFXn\":false},\"notification_sent\":false,\"time_elapsed\":488741644,\"credential_timeout\":272570080,\"auth_percent_complete\":56642461,\"percent_complete\":818184615,\"started_on\":\"1981-12-19T21:43:37.659Z\",\"completed_on\":\"1992-08-02T10:50:19.487Z\",\"use_puppeteer\":true}"
-X POST -H "Content-Type: application/json"
-H "x-cardsavr-cardholder-safe-key: CARDHOLDER_SAFE_KEY"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/place_card_on_single_site_jobs/
Path
POST /place_card_on_single_site_jobs
Description
Create a single-site job and return the created object.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Required | Description |
---|---|---|---|
cardholder_id | number | yes | ID of cardholder associated with this job. |
card_id | number | yes | ID of card associated with this job. |
account_id | number | yes | ID of account associated with this job. |
status | string enum* | no | Current status of job (e.g. pending_tfa). These names are dynamic and change frequently, so it is best to use status_message to communicate with cardholders. |
custom_data | object | no | |
notification_sent | boolean | no | Indicates if a notification has been sent or posted for this job. |
time_elapsed | number | no | Amount of time elapsed since the creation of the job. |
credential_timeout | number | no | Credential timeout value in seconds. |
auth_percent_complete | number | no | |
percent_complete | number | no | |
started_on | date | no | Time when job started. |
completed_on | date | no | Timestamp of job completion. |
use_puppeteer | boolean | no | whether or not the VBS will use puppeteer instead of playwright. |
See single-site job response attributes.
string enum*
- INITIATED
- REQUESTED
- IN_PROGRESS
- AUTH
- LOGIN_SUBMITTED
- CREDS_RECEIVED
- TFA_CODE_RECEIVED
- TFA_SUBMITTED
- SUBMITTED
- PENDING_NEWCREDS
- PENDING_TFA
- PENDING
- UPDATING
- QUEUED
- SITE_BLOCKED
- CANCEL_REQUESTED
- CANCELLED
- CANCELLED_QUICKSTART
- JOB_RECORD_DELETED
- ABANDONED
- ABANDONED_QUICKSTART
- KILLED
- ACCOUNT_SETUP_INCOMPLETE
- ACCOUNT_NOT_SUPPORTED
- TFA_NOT_SUPPORTED
- PREPAID_ACCOUNT
- INACTIVE_ACCOUNT
- MISSING_CARD_DATA
- CARD_FORM_FAILED
- UNEXPECTED_ERROR
- INVALID_CARD_DETAILS
- INVALID_CARD_TYPE
- MULTI_ACCOUNT_CARD_NOT_ALLOWED
- INVALID_ADDRESS
- PASSWORD_RESET_REQUIRED
- BUNDLED_SUBSCRIPTION
- FREE_ACCOUNT
- ACCOUNT_LOCKED
- INVALID_EXPIRATION_DATE
- EXPIRED_CARD
- INVALID_CVV
- INVALID_NETWORK
- MAX_LIMIT_OF_STORED_CARDS
- PAYMENT_PROCESSOR_DOWN
- DUPLICATE_CARD
- TEST_COMPLETE_SUCCESS
- SUCCESSFUL
- UNSUPPORTED_CAPTCHA
- TIMEOUT_CAPTCHA
- TIMEOUT_CREDENTIALS
- MISSING_CREDENTIALS
- TIMEOUT_TFA
- TOO_MANY_LOGIN_FAILURES
- TOO_MANY_TFA_FAILURES
- TOO_MANY_OTP_FAILURES
- INVALID_SECURITY_ANSWERS
- INVALID_CREDENTIAL_REQUEST_TYPE
- UNSUCCESSFUL
- PROXY_PROBE_FAILED
- VBS_TIMEOUT
- VBS_ERROR
- UNKNOWN_INTERFACE_TYPE
- UNIMPLEMENTED_JOB_TYPE
- UNKNOWN_JOB_TYPE
- INTERNAL_ERROR
- ACCOUNT_NOT_FOUND
- MERCHANT_SECURITY_NOT_IMPLEMENTED
- MERCHANT_PROCESSOR_NOT_IMPLEMENTED
- WALLET_PROCESSOR_NOT_IMPLEMENTED
string enum**
- USER_DATA_FAILURE
- PROCESS_FAILURE
- SITE_INTERACTION_FAILURE
- BILLABLE
- NEVER_STARTED
Update single-site job
const singlesitejob = await session.updateSingleSiteJob(1,{
"card_id": 401740834,
"status": "INVALID_SECURITY_ANSWERS",
"custom_data": {
"LcRGycCzblbO": "+Sp4Fab7)(hM=IrX=Vb^YL",
"pWbfpuayjBXp": 71,
"fYlfJCCskVCH": false
},
"notification_sent": true,
"time_elapsed": 1792363815,
"auth_percent_complete": 1190904038,
"percent_complete": 1842028782,
"started_on": "2019-04-03T02:53:22.522Z",
"completed_on": "1978-09-26T09:06:54.052Z",
"use_puppeteer": false
}, CARDHOLDER_SAFE_KEY);
PropertyBag body = new PropertyBag()
{
{ "card_id", 401740834 },
{ "status", "INVALID_SECURITY_ANSWERS" },
{ "notification_sent", true },
{ "time_elapsed", 1792363815 },
{ "auth_percent_complete", 1190904038 },
{ "percent_complete", 1842028782 },
{ "started_on", "2019-04-03T02:53:22.522Z" },
{ "completed_on", "1978-09-26T09:06:54.052Z" },
{ "use_puppeteer", false }
};
CardSavrResponse<SingleSiteJob> singlesitejob = await http.UpdateSingleSiteJobAsync(body, CARDHOLDER_SAFE_KEY);
JsonObject body = Json.createObjectBuilder()
.add("card_id", 401740834 )
.add("status", "INVALID_SECURITY_ANSWERS" )
.add("notification_sent", true )
.add("time_elapsed", 1792363815 )
.add("auth_percent_complete", 1190904038 )
.add("percent_complete", 1842028782 )
.add("started_on", "2019-04-03T02:53:22.522Z" )
.add("completed_on", "1978-09-26T09:06:54.052Z" )
.add("use_puppeteer", false )
.build();
JsonValue singlesitejob = session.put("/place_card_on_single_site_jobs", body, null, null);
curl -d "{\"card_id\":401740834,\"status\":\"INVALID_SECURITY_ANSWERS\",\"custom_data\":{\"LcRGycCzblbO\":\"+Sp4Fab7)(hM=IrX=Vb^YL\",\"pWbfpuayjBXp\":71,\"fYlfJCCskVCH\":false},\"notification_sent\":true,\"time_elapsed\":1792363815,\"auth_percent_complete\":1190904038,\"percent_complete\":1842028782,\"started_on\":\"2019-04-03T02:53:22.522Z\",\"completed_on\":\"1978-09-26T09:06:54.052Z\",\"use_puppeteer\":false}"
-X PUT -H "Content-Type: application/json"
-H "cardholder-safe-key: CARDHOLDER_SAFE_KEY"
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/place_card_on_single_site_jobs/750836597
Path
PUT /place_card_on_single_site_jobs OR /place_card_on_single_site_jobs/{id}
Description
Update a single-site job and return the updated object. An id is required on every update request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
Body parameters
Parameter | Type | Description |
---|---|---|
card_id | number | ID of card associated with this job. |
status | string enum* | Current status of job (e.g. pending_tfa). These names are dynamic and change frequently, so it is best to use status_message to communicate with cardholders. |
custom_data | object | |
notification_sent | boolean | Indicates if a notification has been sent or posted for this job. |
time_elapsed | number | Amount of time elapsed since the creation of the job. |
auth_percent_complete | number | |
percent_complete | number | |
started_on | date | Time when job started. |
completed_on | date | Timestamp of job completion. |
use_puppeteer | boolean | whether or not the VBS will use puppeteer instead of playwright. |
See single-site job response parameters.
Delete single-site job
curl -X DELETE
-H "x-cardsavr-trace:{\"key\": \"my_trace\"}"
https://api.INSTANCE.cardsavr.io/place_card_on_single_site_jobs/750836597
await session.deleteSingleSiteJob(undefined);
CardSavrResponse<SingleSiteJob> singlesitejob = await http.DeleteSingleSiteJobAsync(undefined);
JsonValue singlesitejob = session.delete("/place_card_on_single_site_jobs", undefined, null);
Path
DELETE /place_card_on_single_site_jobs/{id}
Description
Delete a single-site job and purge its related items. An id is required on every delete request.
SDK Usage
Please visit the javascript, c sharp, and java SDKs for further examples and information on SDK usage.
See single-site job response parameters.
Client Messages
Subscribe to Status Updates
Before you can listen to a channel, you must first subscribe. Unlike credential requests, multiple clients can listen to messages for the same job.
const session = this.getSession(username);
const subscription = await session.registerForJobStatusUpdates(job_id);
//this key is necessary for all future requests
const key = subscription.body.access_key;
//not implemented
//not implemented
#session must first be started, and must have permissions
curl -iv
-H "Content-Type: application/json" "https://api.INSTANCE.cardsavr.io/messages/place_card_on_single_site_jobs/123/broadcasts/registrations"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
access_key is required for all future requests for status updates. Messages are returned as an array. status is always job_status
{
"access_key": "erz5nk219FPZNWGv3AbHdA=="
}
Path
GET /messages/place_card_on_single_site_jobs/job_id:/broadcasts/registrations
Description
Registers a client to a broadcast message channel. Messages are saved for an hour waiting for the client to poll. Generally clients poll every 3-5 seconds. Multiple clients can poll for messages for the same job, so each client has its own access key.
Note: Creating a place_card_on_single_site_job will automatically create a subscription to a job and return an access_key. Thereforce explicit subscription is only for higher privileged agents that didn't actually create the job.
Get Job Status Updates
The unique access key is returned for every broadcast message poll request
const broadcast_probe = setInterval(async () => {
const update = await session.getJobStatusUpdate(job_id, subscription.body.access_key);
if (update.status_code == 401) {
clearInterval(broadcast_probe);
} else if (update.body) {
update.body.map((item: any) => {
callback(item); //process message "item"
if (item.type === "job_status") {
if (item.message.termination_type || item.message.percent_complete == 100) { //job is completed, stop probing
clearInterval(broadcast_probe);
}
}
});
}
}, 5000);
Not implemented yet
curl -iv -H "Content-Type: application/json"
"https://api.INSTANCE.cardsavr.io/messages/place_card_on_single_site_jobs/123/broadcasts/"
-H "cardsavr-messaging-access-key: erz5nk219FPZNWGv3AbHdA=="
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
Response is an array, as mutliple messages may be generated between polls.
[
{
"type": "job_status",
"message": {
"job_timeout": 856058,
"percent_complete": 30,
"status": "AUTH"
},
"job_id": 123
},
{
"type": "job_status",
"message": {
"job_timeout": 855737,
"percent_complete": 54,
"status": "UPDATING"
},
"job_id": 123
}
]
Path
GET /messages/place_card_on_single_site_jobs/job_id:/broadcasts
Description
Grabs the status messages for this job. If there are no messages, none are returned. Since multiple messages may be returned, the body is an array of messages. When jobs complete, the final message will have a "termination_type" with values:
Termination type | Description |
---|---|
BILLABLE | Job completed successfully |
USER_DATA_FAILURE | There was an issue with data supplied by the cardholder like a TFA code or password |
SITE_INTERACTION_FAILURE | Cardsavr was unable to definitively place the card on the site |
PROCESS_FAILURE | There was an internal system failure - these happen very rarely and should be escallated immediately |
Get Cardholder Status Updates
The unique access key is returned for every broadcast message poll request
const messages = await session.getCardholderMessages(cardholder_id);
if (messages.body) {
messages.body.map(async (item) => {
if (item.type === "job_status") {
conssole.log(item.status);
}
});
}
Not implemented yet
Not implemented yet
curl -iv -H "Content-Type: application/json"
"https://api.INSTANCE.cardsavr.io/messages/cardholders/123/"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
Response is an array, as mutliple messages from multiple jobs may be generated between polls.
[
{
"job_id": "1585",
"type": "job_status",
"message": {
"status": "AUTH",
"job_timeout": 781440,
"percent_complete": 5
}
},
{
"job_id": "1586",
"type": "job_status",
"message": {
"status": "AUTH",
"job_timeout": 781254,
"percent_complete": 5
}
}
]
Path
GET /messages/cardholders/cardholder_id
Description
Grabs the status messages for this cardholder. If there are no messages, none are returned. When runniung multiple jobs, this is much more efficient mechanism for retrieving messaages. You do not need to manage acceess_keys since the permissions are managed via the cardholder agent's permissions. Since multiple job and messages may be returned, the body is an array of messages. As jobs complete, the final message for each job will have a "termination_type" with values:
Termination type | Description |
---|---|
BILLABLE | Job completed successfully |
USER_DATA_FAILURE | There was an issue with data supplied by the cardholder like a TFA code or password |
SITE_INTERACTION_FAILURE | Cardsavr was unable to definitively place the card on the site |
PROCESS_FAILURE | There was an internal system failure - these happen very rarely and should be escallated immediately |
Get Credential Requests
Credential requests must be polled for using the job_id. Permissions are established based on the role and the owner of the job.
const request_probe = setInterval(async () => {
const request = await session.getJobInformationRequest(job_id);
if (request.body) {
callback(request.body); //callback is a function that processes the message.
}
}, 5000);
//not implemented
// not implemented
# With a shell, you must first establish a sessionby logging in.
# All calls must be accompanied by the session token. This only works on a dev
# server with authentication optional.
curl "https://api.INSTANCE.cardsavr.io/messages/place_card_on_single_site_jobs/123/broadcasts"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
The response contains a unique request envelope id which must be returned with the response.
{
"type": "tfa_request",
"job_id": 101,
"envelope_id": "uHsa6mI3GYO2ZwOf82SuaA=="
}
Path
GET /messages/place_card_on_single_site_jobs/job_id:/credential_requests
Description
Polls the server for requests from the virtual browser session. This might be new credentials or a TFA code. You must use the envelope_id that was returned with the initial request message.
Post Credential Response
Jobs wiill wait until a credential response is posted.
const session = this.getSession(username); //session should already be loaded
session.sendJobInformation(job_id, envelope_id, "tfa_response", "1234");
//not implemented
#session must first be started
curl -iv -X POST -d "{\"envelope_id\": \"uHsa6mI3GYO2ZwOf82SuaA==\", \"type\": \"tfa_request\", \"message\": \"1234\"}"
-H "Content-Type: application/json" "https://api.INSTANCE.cardsavr.io/messages/place_card_on_single_site_jobs/123/credential_responses"
-H "x-cardsavr-trace: {\"key\": \"my_trace\"}" -H "x-cardsavr-session-jwt: {{JWT_TOKEN}}"
The response returns a 200 if the post succeeds correctly. There are better mechanisms for posting credentials using hydrated api calls outlined in the Messaging system documentation
{
"type": "credential_response",
"job_id": 101,
"envelope_id": "uHsa6mI3GYO2ZwOf82SuaA==",
"message": "submitted"
}
Path
POST /messages/place_card_on_single_site_jobs/job_id:/credential_responses
Description
Post the response to a TFA request or a bad credential request
Body parameters
Parameter | Type | Required | Desription |
---|---|---|---|
envelope_id | string | yes | unique key associated with the original request |
type | string | yes | credential_request or tfa_request |
message | string | yes | "success" for credential resubmissions, and the tfa code entered by the cardholder for TFA responses |
Errors
The Strivve API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API key is wrong. |
403 | Forbidden -- The request is hidden for administrators only. |
404 | Not Found -- The specified entity could not be found. |
405 | Method Not Allowed -- You tried to access an entity with an invalid method. |
406 | Not Acceptable -- You requested a format that isn't json. |
429 | Too Many Requests -- You're requesting too many entities! Slow down! |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |