diff --git a/generator/cybersource-java-config.json b/generator/cybersource-java-config.json new file mode 100644 index 000000000..6e537273c --- /dev/null +++ b/generator/cybersource-java-config.json @@ -0,0 +1,5 @@ +{ + "modelPackage" : "Model", + "apiPackage" : "Api", + "invokerPackage" : "Invokers" +} \ No newline at end of file diff --git a/generator/cybersource-java-template/ApiClient.mustache b/generator/cybersource-java-template/ApiClient.mustache new file mode 100644 index 000000000..9fe8d5561 --- /dev/null +++ b/generator/cybersource-java-template/ApiClient.mustache @@ -0,0 +1,728 @@ +{{>licenseInfo}} +package {{invokerPackage}}; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.*; +{{#java8}} +import com.fasterxml.jackson.datatype.jsr310.*; +{{/java8}} +{{^java8}} +import com.fasterxml.jackson.datatype.joda.*; +{{/java8}} +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.GenericType; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.api.client.filter.GZIPContentEncodingFilter; +import com.sun.jersey.api.client.filter.LoggingFilter; +import com.sun.jersey.api.client.WebResource.Builder; + +import com.sun.jersey.multipart.FormDataMultiPart; +import com.sun.jersey.multipart.file.FileDataBodyPart; + +import javax.ws.rs.core.Response.Status.Family; +import javax.ws.rs.core.MediaType; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Date; +import java.util.TimeZone; + +import java.net.URLEncoder; + +import java.io.File; +import java.io.UnsupportedEncodingException; + +import java.text.DateFormat; + +import {{invokerPackage}}.auth.Authentication; +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; + +{{>generatedAnnotation}} +public class ApiClient { + private Map defaultHeaderMap = new HashMap(); + private String basePath = "{{{basePath}}}"; + private boolean debugging = false; + private int connectionTimeout = 0; + + private Client httpClient; + private ObjectMapper objectMapper; + + private Map authentications; + + private int statusCode; + private Map> responseHeaders; + + private DateFormat dateFormat; + + public ApiClient() { + objectMapper = new ObjectMapper(); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + {{#java8}} + objectMapper.registerModule(new JavaTimeModule()); + {{/java8}} + {{^java8}} + objectMapper.registerModule(new JodaModule()); + {{/java8}} + objectMapper.setDateFormat(ApiClient.buildDefaultDateFormat()); + + dateFormat = ApiClient.buildDefaultDateFormat(); + + // Set default User-Agent. + setUserAgent("{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}Swagger-Codegen/{{{artifactVersion}}}/java{{/httpUserAgent}}"); + + // Setup authentications (key: authentication name, value: authentication). + authentications = new HashMap();{{#authMethods}}{{#isBasic}} + authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}} + authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}} + authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}} + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + + rebuildHttpClient(); + } + + public static DateFormat buildDefaultDateFormat() { + return new RFC3339DateFormat(); + } + + /** + * Build the Client used to make HTTP requests with the latest settings, + * i.e. objectMapper and debugging. + * TODO: better to use the Builder Pattern? + * @return API client + */ + public ApiClient rebuildHttpClient() { + // Add the JSON serialization support to Jersey + JacksonJsonProvider jsonProvider = new JacksonJsonProvider(objectMapper); + DefaultClientConfig conf = new DefaultClientConfig(); + conf.getSingletons().add(jsonProvider); + Client client = Client.create(conf); + client.addFilter(new GZIPContentEncodingFilter({{#useGzipFeature}}true{{/useGzipFeature}}{{^useGzipFeature}}false{{/useGzipFeature}})); + if (debugging) { + client.addFilter(new LoggingFilter()); + } + this.httpClient = client; + return this; + } + + /** + * Returns the current object mapper used for JSON serialization/deserialization. + *

+ * Note: If you make changes to the object mapper, remember to set it back via + * setObjectMapper in order to trigger HTTP client rebuilding. + *

+ * @return Object mapper + */ + public ObjectMapper getObjectMapper() { + return objectMapper; + } + + public ApiClient setObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + // Need to rebuild the Client as it depends on object mapper. + rebuildHttpClient(); + return this; + } + + public Client getHttpClient() { + return httpClient; + } + + public ApiClient setHttpClient(Client httpClient) { + this.httpClient = httpClient; + return this; + } + + public String getBasePath() { + return basePath; + } + + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Gets the status code of the previous request + * @return Status code + */ + public int getStatusCode() { + return statusCode; + } + + /** + * Gets the response headers of the previous request + * @return Response headers + */ + public Map> getResponseHeaders() { + return responseHeaders; + } + + /** + * Get authentications (key: authentication name, value: authentication). + * @return Map of authentication + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + * @param username Username + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + * @param password Password + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + * @param apiKey API key + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + * @param apiKeyPrefix API key prefix + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set access token for the first OAuth2 authentication. + * @param accessToken Access token + */ + public void setAccessToken(String accessToken) { + for (Authentication auth : authentications.values()) { + if (auth instanceof OAuth) { + ((OAuth) auth).setAccessToken(accessToken); + return; + } + } + throw new RuntimeException("No OAuth2 authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + * @param userAgent User agent + * @return API client + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + * @return API client + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + * @return True if debugging is on + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + * @return API client + */ + public ApiClient setDebugging(boolean debugging) { + this.debugging = debugging; + // Need to rebuild the Client as it depends on the value of debugging. + rebuildHttpClient(); + return this; + } + + /** + * Connect timeout (in milliseconds). + * @return Connection timeout + */ + public int getConnectTimeout() { + return connectionTimeout; + } + + /** + * Set the connect timeout (in milliseconds). + * A value of 0 means no timeout, otherwise values must be between 1 and + * {@link Integer#MAX_VALUE}. + * @param connectionTimeout Connection timeout in milliseconds + * @return API client + */ + public ApiClient setConnectTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + httpClient.setConnectTimeout(connectionTimeout); + return this; + } + + /** + * Get the date format used to parse/format date parameters. + * @return Date format + */ + public DateFormat getDateFormat() { + return dateFormat; + } + + /** + * Set the date format used to parse/format date parameters. + * @param dateFormat Date format + * @return API client + */ + public ApiClient setDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + // Also set the date format for model (de)serialization with Date properties. + this.objectMapper.setDateFormat((DateFormat) dateFormat.clone()); + // Need to rebuild the Client as objectMapper changes. + rebuildHttpClient(); + return this; + } + + /** + * Parse the given string into Date object. + * @param str String + * @return Date + */ + public Date parseDate(String str) { + try { + return dateFormat.parse(str); + } catch (java.text.ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * Format the given Date object into string. + * @param date Date + * @return Date in string format + */ + public String formatDate(Date date) { + return dateFormat.format(date); + } + + /** + * Format the given parameter object into string. + * @param param Object + * @return Object in string format + */ + public String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date) { + return formatDate((Date) param); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for(Object o : (Collection)param) { + if(b.length() > 0) { + b.append(','); + } + b.append(String.valueOf(o)); + } + return b.toString(); + } else { + return String.valueOf(param); + } + } + + /* + * Format to {@code Pair} objects. + * @param collectionFormat Collection format + * @param name Name + * @param value Value + * @return List of pair + */ + public List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList(); + + // preconditions + if (name == null || name.isEmpty() || value == null) return params; + + Collection valueCollection; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); + return params; + } + + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format + String format = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv + + // create the params based on the collection format + if ("multi".equals(format)) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); + } + + return params; + } + + String delimiter = ","; + + if ("csv".equals(format)) { + delimiter = ","; + } else if ("ssv".equals(format)) { + delimiter = " "; + } else if ("tsv".equals(format)) { + delimiter = "\t"; + } else if ("pipes".equals(format)) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + + return params; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime MIME + * @return True if MIME type is boolean + */ + public boolean isJsonMime(String mime) { + String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"; + return mime != null && (mime.matches(jsonMime) || mime.equalsIgnoreCase("application/json-patch+json")); + } + + /** + * Select the Accept header's value from the given accepts array: + * if JSON exists in the given array, use it; + * otherwise use all of them (joining into a string) + * + * @param accepts The accepts array to select from + * @return The Accept header to use. If the given array is empty, + * null will be returned (not to set the Accept header explicitly). + */ + public String selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) { + return null; + } + for (String accept : accepts) { + if (isJsonMime(accept)) { + return accept; + } + } + return StringUtil.join(accepts, ","); + } + + /** + * Select the Content-Type header's value from the given array: + * if JSON exists in the given array, use it; + * otherwise use the first one of the array. + * + * @param contentTypes The Content-Type array to select from + * @return The Content-Type header to use. If the given array is empty, + * JSON will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0) { + return "application/json"; + } + for (String contentType : contentTypes) { + if (isJsonMime(contentType)) { + return contentType; + } + } + return contentTypes[0]; + } + + /** + * Escape the given string to be used as URL query value. + * @param str String + * @return Escaped string + */ + public String escapeString(String str) { + try { + return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + /** + * Serialize the given Java object into string according the given + * Content-Type (only JSON is supported for now). + * @param obj Object + * @param contentType Content type + * @param formParams Form parameters + * @return Object + * @throws ApiException API exception + */ + public Object serialize(Object obj, String contentType, Map formParams) throws ApiException { + if (contentType.startsWith("multipart/form-data")) { + FormDataMultiPart mp = new FormDataMultiPart(); + for (Entry param: formParams.entrySet()) { + if( param.getValue() instanceof List && !( ( List ) param.getValue() ).isEmpty() + && ( ( List ) param.getValue() ).get( 0 ) instanceof File ) { + @SuppressWarnings( "unchecked" ) + List files = ( List ) param.getValue(); + for( File file : files ) { + mp.bodyPart( new FileDataBodyPart( param.getKey(), file, MediaType.APPLICATION_OCTET_STREAM_TYPE ) ); + } + } else if (param.getValue() instanceof File) { + File file = (File) param.getValue(); + mp.bodyPart(new FileDataBodyPart(param.getKey(), file, MediaType.APPLICATION_OCTET_STREAM_TYPE)); + } else { + mp.field(param.getKey(), parameterToString(param.getValue()), MediaType.MULTIPART_FORM_DATA_TYPE); + } + } + return mp; + } else if (contentType.startsWith("application/x-www-form-urlencoded")) { + return this.getXWWWFormUrlencodedParams(formParams); + } else { + // We let Jersey attempt to serialize the body + return obj; + } + } + + /** + * Build full URL by concatenating base path, the given sub path and query parameters. + * + * @param path The sub path + * @param queryParams The query parameters + * @return The full URL + */ + private String buildUrl(String path, List queryParams) { + final StringBuilder url = new StringBuilder(); + url.append(basePath).append(path); + + if (queryParams != null && !queryParams.isEmpty()) { + // support (constant) query string in `path`, e.g. "/posts?draft=1" + String prefix = path.contains("?") ? "&" : "?"; + for (Pair param : queryParams) { + if (param.getValue() != null) { + if (prefix != null) { + url.append(prefix); + prefix = null; + } else { + url.append("&"); + } + String value = parameterToString(param.getValue()); + url.append(escapeString(param.getName())).append("=").append(escapeString(value)); + } + } + } + + return url.toString(); + } + + private ClientResponse getAPIResponse(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames) throws ApiException { + if (body != null && !formParams.isEmpty()) { + throw new ApiException(500, "Cannot have body and form params"); + } + + updateParamsForAuth(authNames, queryParams, headerParams); + + final String url = buildUrl(path, queryParams); + Builder builder; + if (accept == null) { + builder = httpClient.resource(url).getRequestBuilder(); + } else { + builder = httpClient.resource(url).accept(accept); + } + + for (String key : headerParams.keySet()) { + builder = builder.header(key, headerParams.get(key)); + } + for (String key : defaultHeaderMap.keySet()) { + if (!headerParams.containsKey(key)) { + builder = builder.header(key, defaultHeaderMap.get(key)); + } + } + + ClientResponse response = null; + + if ("GET".equals(method)) { + response = (ClientResponse) builder.get(ClientResponse.class); + } else if ("POST".equals(method)) { + response = builder.type(contentType).post(ClientResponse.class, serialize(body, contentType, formParams)); + } else if ("PUT".equals(method)) { + response = builder.type(contentType).put(ClientResponse.class, serialize(body, contentType, formParams)); + } else if ("DELETE".equals(method)) { + response = builder.type(contentType).delete(ClientResponse.class, serialize(body, contentType, formParams)); + } else if ("PATCH".equals(method)) { + response = builder.type(contentType).header("X-HTTP-Method-Override", "PATCH").post(ClientResponse.class, serialize(body, contentType, formParams)); + } + else { + throw new ApiException(500, "unknown method type " + method); + } + return response; + } + + /** + * Invoke API by sending HTTP request with the given options. + * + * @param Type + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "POST", "PUT", and "DELETE" + * @param queryParams The query parameters + * @param body The request body object - if it is not binary, otherwise null + * @param headerParams The header parameters + * @param formParams The form parameters + * @param accept The request's Accept header + * @param contentType The request's Content-Type header + * @param authNames The authentications to apply + * @param returnType Return type + * @return The response body in type of string + * @throws ApiException API exception + */ + public T invokeAPI(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames, GenericType returnType) throws ApiException { + + ClientResponse response = getAPIResponse(path, method, queryParams, body, headerParams, formParams, accept, contentType, authNames); + + statusCode = response.getStatusInfo().getStatusCode(); + responseHeaders = response.getHeaders(); + + if(response.getStatusInfo().getStatusCode() == ClientResponse.Status.NO_CONTENT.getStatusCode()) { + return null; + } else if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) { + if (returnType == null) + return null; + else + return response.getEntity(returnType); + } else { + String message = "error"; + String respBody = null; + if (response.hasEntity()) { + try { + respBody = response.getEntity(String.class); + message = respBody; + } catch (RuntimeException e) { + // e.printStackTrace(); + } + } + throw new ApiException( + response.getStatusInfo().getStatusCode(), + message, + response.getHeaders(), + respBody); + } + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames The authentications to apply + * @param queryParams Query parameters + * @param headerParams Header parameters + */ + private void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); + auth.applyToParams(queryParams, headerParams); + } + } + + /** + * Encode the given form parameters as request body. + * @param formParams Form parameters + * @return HTTP form encoded parameters + */ + private String getXWWWFormUrlencodedParams(Map formParams) { + StringBuilder formParamBuilder = new StringBuilder(); + + for (Entry param : formParams.entrySet()) { + String valueStr = parameterToString(param.getValue()); + try { + formParamBuilder.append(URLEncoder.encode(param.getKey(), "utf8")) + .append("=") + .append(URLEncoder.encode(valueStr, "utf8")); + formParamBuilder.append("&"); + } catch (UnsupportedEncodingException e) { + // move on to next + } + } + + String encodedFormParams = formParamBuilder.toString(); + if (encodedFormParams.endsWith("&")) { + encodedFormParams = encodedFormParams.substring(0, encodedFormParams.length() - 1); + } + + return encodedFormParams; + } +} diff --git a/generator/cybersource-java-template/BeanValidationException.mustache b/generator/cybersource-java-template/BeanValidationException.mustache new file mode 100644 index 000000000..ab8ef30b6 --- /dev/null +++ b/generator/cybersource-java-template/BeanValidationException.mustache @@ -0,0 +1,27 @@ +package {{invokerPackage}}; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.ValidationException; + +public class BeanValidationException extends ValidationException { + /** + * + */ + private static final long serialVersionUID = -5294733947409491364L; + Set> violations; + + public BeanValidationException(Set> violations) { + this.violations = violations; + } + + public Set> getViolations() { + return violations; + } + + public void setViolations(Set> violations) { + this.violations = violations; + } + +} diff --git a/generator/cybersource-java-template/Configuration.mustache b/generator/cybersource-java-template/Configuration.mustache new file mode 100644 index 000000000..cb425df35 --- /dev/null +++ b/generator/cybersource-java-template/Configuration.mustache @@ -0,0 +1,28 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +{{>generatedAnnotation}} +public class Configuration { + private static ApiClient defaultApiClient = new ApiClient(); + + /** + * Get the default API client, which would be used when creating API + * instances without providing an API client. + * + * @return Default API client + */ + public static ApiClient getDefaultApiClient() { + return defaultApiClient; + } + + /** + * Set the default API client, which would be used when creating API + * instances without providing an API client. + * + * @param apiClient API client + */ + public static void setDefaultApiClient(ApiClient apiClient) { + defaultApiClient = apiClient; + } +} diff --git a/generator/cybersource-java-template/Pair.mustache b/generator/cybersource-java-template/Pair.mustache new file mode 100644 index 000000000..c08f145a4 --- /dev/null +++ b/generator/cybersource-java-template/Pair.mustache @@ -0,0 +1,41 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +{{>generatedAnnotation}} +public class Pair { + private String name = ""; + private String value = ""; + + public Pair (String name, String value) { + setName(name); + setValue(value); + } + + private void setName(String name) { + if (!isValidString(name)) return; + + this.name = name; + } + + private void setValue(String value) { + if (!isValidString(value)) return; + + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private boolean isValidString(String arg) { + if (arg == null) return false; + if (arg.trim().isEmpty()) return false; + + return true; + } +} diff --git a/generator/cybersource-java-template/README.mustache b/generator/cybersource-java-template/README.mustache new file mode 100644 index 000000000..fff0bf097 --- /dev/null +++ b/generator/cybersource-java-template/README.mustache @@ -0,0 +1,148 @@ +# {{artifactId}} + +## Requirements + +Building the API client library requires [Maven](https://maven.apache.org/) to be installed. + +## Installation + +To install the API client library to your local Maven repository, simply execute: + +```shell +mvn install +``` + +To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: + +```shell +mvn deploy +``` + +Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information. + +### Maven users + +Add this dependency to your project's POM: + +```xml + + {{{groupId}}} + {{{artifactId}}} + {{{artifactVersion}}} + compile + +``` + +### Gradle users + +Add this dependency to your project's build file: + +```groovy +compile "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}" +``` + +### Others + +At first generate the JAR by executing: + + mvn package + +Then manually install the following JARs: + +* target/{{{artifactId}}}-{{{artifactVersion}}}.jar +* target/lib/*.jar + +## Getting Started + +Please follow the [installation](#installation) instruction and execute the following Java code: + +```java +{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}} +import {{{invokerPackage}}}.*; +import {{{invokerPackage}}}.auth.*; +import {{{modelPackage}}}.*; +import {{{package}}}.{{{classname}}}; + +import java.io.File; +import java.util.*; + +public class {{{classname}}}Example { + + public static void main(String[] args) { + {{#hasAuthMethods}}ApiClient defaultClient = Configuration.getDefaultApiClient(); + {{#authMethods}}{{#isBasic}} + // Configure HTTP basic authorization: {{{name}}} + HttpBasicAuth {{{name}}} = (HttpBasicAuth) defaultClient.getAuthentication("{{{name}}}"); + {{{name}}}.setUsername("YOUR USERNAME"); + {{{name}}}.setPassword("YOUR PASSWORD");{{/isBasic}}{{#isApiKey}} + // Configure API key authorization: {{{name}}} + ApiKeyAuth {{{name}}} = (ApiKeyAuth) defaultClient.getAuthentication("{{{name}}}"); + {{{name}}}.setApiKey("YOUR API KEY"); + // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) + //{{{name}}}.setApiKeyPrefix("Token");{{/isApiKey}}{{#isOAuth}} + // Configure OAuth2 access token for authorization: {{{name}}} + OAuth {{{name}}} = (OAuth) defaultClient.getAuthentication("{{{name}}}"); + {{{name}}}.setAccessToken("YOUR ACCESS TOKEN");{{/isOAuth}} + {{/authMethods}} + {{/hasAuthMethods}} + + {{{classname}}} apiInstance = new {{{classname}}}(); + {{#allParams}} + {{{dataType}}} {{{paramName}}} = {{{example}}}; // {{{dataType}}} | {{{description}}} + {{/allParams}} + try { + {{#returnType}}{{{returnType}}} result = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}} + System.out.println(result);{{/returnType}} + } catch (ApiException e) { + System.err.println("Exception when calling {{{classname}}}#{{{operationId}}}"); + e.printStackTrace(); + } + } +} +{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}} +``` + +## Documentation for API Endpoints + +All URIs are relative to *{{basePath}}* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + +## Documentation for Models + +{{#models}}{{#model}} - [{{classname}}]({{modelDocPath}}{{classname}}.md) +{{/model}}{{/models}} + +## Documentation for Authorization + +{{^authMethods}}All endpoints do not require authorization. +{{/authMethods}}Authentication schemes defined for the API: +{{#authMethods}}### {{name}} + +{{#isApiKey}}- **Type**: API key +- **API key parameter name**: {{keyParamName}} +- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}} +{{/isApiKey}} +{{#isBasic}}- **Type**: HTTP basic authentication +{{/isBasic}} +{{#isOAuth}}- **Type**: OAuth +- **Flow**: {{flow}} +- **Authorization URL**: {{authorizationUrl}} +- **Scopes**: {{^scopes}}N/A{{/scopes}} +{{#scopes}} - {{scope}}: {{description}} +{{/scopes}} +{{/isOAuth}} + +{{/authMethods}} + +## Recommendation + +It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. + +## Author + +{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}} +{{/hasMore}}{{/apis}}{{/apiInfo}} diff --git a/generator/cybersource-java-template/RFC3339DateFormat.mustache b/generator/cybersource-java-template/RFC3339DateFormat.mustache new file mode 100644 index 000000000..16fd2a495 --- /dev/null +++ b/generator/cybersource-java-template/RFC3339DateFormat.mustache @@ -0,0 +1,21 @@ +{{>licenseInfo}} +package {{invokerPackage}}; + +import com.fasterxml.jackson.databind.util.ISO8601DateFormat; +import com.fasterxml.jackson.databind.util.ISO8601Utils; + +import java.text.FieldPosition; +import java.util.Date; + + +public class RFC3339DateFormat extends ISO8601DateFormat { + + // Same as ISO8601DateFormat but serializing milliseconds. + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + String value = ISO8601Utils.format(date, true); + toAppendTo.append(value); + return toAppendTo; + } + +} \ No newline at end of file diff --git a/generator/cybersource-java-template/StringUtil.mustache b/generator/cybersource-java-template/StringUtil.mustache new file mode 100644 index 000000000..7b72a7bab --- /dev/null +++ b/generator/cybersource-java-template/StringUtil.mustache @@ -0,0 +1,44 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +{{>generatedAnnotation}} +public class StringUtil { + /** + * Check if the given array contains the given value (with case-insensitive comparison). + * + * @param array The array + * @param value The value to search + * @return true if the array contains the value + */ + public static boolean containsIgnoreCase(String[] array, String value) { + for (String str : array) { + if (value == null && str == null) return true; + if (value != null && value.equalsIgnoreCase(str)) return true; + } + return false; + } + + /** + * Join an array of strings with the given separator. + *

+ * Note: This might be replaced by utility method from commons-lang or guava someday + * if one of those libraries is added as dependency. + *

+ * + * @param array The array of strings + * @param separator The separator + * @return the resulting string + */ + public static String join(String[] array, String separator) { + int len = array.length; + if (len == 0) return ""; + + StringBuilder out = new StringBuilder(); + out.append(array[0]); + for (int i = 1; i < len; i++) { + out.append(separator).append(array[i]); + } + return out.toString(); + } +} diff --git a/generator/cybersource-java-template/api.mustache b/generator/cybersource-java-template/api.mustache new file mode 100644 index 000000000..6903f4dec --- /dev/null +++ b/generator/cybersource-java-template/api.mustache @@ -0,0 +1,106 @@ +{{>licenseInfo}} +package {{package}}; + +import com.sun.jersey.api.client.GenericType; + +import {{invokerPackage}}.ApiException; +import {{invokerPackage}}.ApiClient; +import {{invokerPackage}}.Configuration; +import {{modelPackage}}.*; +import {{invokerPackage}}.Pair; + +{{#imports}}import {{import}}; +{{/imports}} + + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +{{>generatedAnnotation}} +{{#operations}} +public class {{classname}} { + private ApiClient {{localVariablePrefix}}apiClient; + + public {{classname}}() { + this(Configuration.getDefaultApiClient()); + } + + public {{classname}}(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + public ApiClient getApiClient() { + return {{localVariablePrefix}}apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + {{#operation}} + /** + * {{summary}} + * {{notes}} + {{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} + {{/allParams}} + {{#returnType}} + * @return {{returnType}} + {{/returnType}} + * @throws ApiException if fails to make API call + */ + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException { + Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}; + {{#allParams}}{{#required}} + // verify the required parameter '{{paramName}}' is set + if ({{paramName}} == null) { + throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + } + {{/required}}{{/allParams}} + // create path and map variables + String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}} + .replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; + + // query params + {{javaUtilPrefix}}List {{localVariablePrefix}}localVarQueryParams = new {{javaUtilPrefix}}ArrayList(); + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarHeaderParams = new {{javaUtilPrefix}}HashMap(); + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarFormParams = new {{javaUtilPrefix}}HashMap(); + + {{#queryParams}} + {{localVariablePrefix}}localVarQueryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); + {{/queryParams}} + + {{#headerParams}}if ({{paramName}} != null) + {{localVariablePrefix}}localVarHeaderParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}})); + {{/headerParams}} + + {{#formParams}}if ({{paramName}} != null) + {{localVariablePrefix}}localVarFormParams.put("{{baseName}}", {{paramName}}); + {{/formParams}} + + final String[] {{localVariablePrefix}}localVarAccepts = { + {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} + }; + final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts); + + final String[] {{localVariablePrefix}}localVarContentTypes = { + {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} + }; + final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes); + + String[] {{localVariablePrefix}}localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; + + {{#returnType}} + GenericType<{{{returnType}}}> {{localVariablePrefix}}localVarReturnType = new GenericType<{{{returnType}}}>() {}; + return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, {{localVariablePrefix}}localVarReturnType); + {{/returnType}}{{^returnType}} + {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, null); + {{/returnType}} + } + {{/operation}} +} +{{/operations}} diff --git a/generator/cybersource-java-template/apiException.mustache b/generator/cybersource-java-template/apiException.mustache new file mode 100644 index 000000000..5b450c9ba --- /dev/null +++ b/generator/cybersource-java-template/apiException.mustache @@ -0,0 +1,80 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import java.util.Map; +import java.util.List; + +{{>generatedAnnotation}} +public class ApiException extends{{#useRuntimeException}} RuntimeException {{/useRuntimeException}}{{^useRuntimeException}} Exception {{/useRuntimeException}}{ + private int code = 0; + private Map> responseHeaders = null; + private String responseBody = null; + + public ApiException() {} + + public ApiException(Throwable throwable) { + super(throwable); + } + + public ApiException(String message) { + super(message); + } + + public ApiException(String message, Throwable throwable, int code, Map> responseHeaders, String responseBody) { + super(message, throwable); + this.code = code; + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + public ApiException(String message, int code, Map> responseHeaders, String responseBody) { + this(message, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(String message, Throwable throwable, int code, Map> responseHeaders) { + this(message, throwable, code, responseHeaders, null); + } + + public ApiException(int code, Map> responseHeaders, String responseBody) { + this((String) null, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(int code, String message) { + super(message); + this.code = code; + } + + public ApiException(int code, String message, Map> responseHeaders, String responseBody) { + this(code, message); + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + /** + * Get the HTTP status code. + * + * @return HTTP status code + */ + public int getCode() { + return code; + } + + /** + * Get the HTTP response headers. + * + * @return A map of list of string + */ + public Map> getResponseHeaders() { + return responseHeaders; + } + + /** + * Get the HTTP response body. + * + * @return Response body in the form of string + */ + public String getResponseBody() { + return responseBody; + } +} diff --git a/generator/cybersource-java-template/api_doc.mustache b/generator/cybersource-java-template/api_doc.mustache new file mode 100644 index 000000000..bbb5b66f8 --- /dev/null +++ b/generator/cybersource-java-template/api_doc.mustache @@ -0,0 +1,82 @@ +# {{classname}}{{#description}} +{{description}}{{/description}} + +All URIs are relative to *{{basePath}}* + +Method | HTTP request | Description +------------- | ------------- | ------------- +{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}} +{{/operation}}{{/operations}} + +{{#operations}} +{{#operation}} + +# **{{operationId}}** +> {{#returnType}}{{returnType}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) + +{{summary}}{{#notes}} + +{{notes}}{{/notes}} + +### Example +```java +// Import classes:{{#hasAuthMethods}} +//import {{{invokerPackage}}}.ApiClient;{{/hasAuthMethods}} +//import {{{invokerPackage}}}.ApiException;{{#hasAuthMethods}} +//import {{{invokerPackage}}}.Configuration; +//import {{{invokerPackage}}}.auth.*;{{/hasAuthMethods}} +//import {{{package}}}.{{{classname}}}; + +{{#hasAuthMethods}} +ApiClient defaultClient = Configuration.getDefaultApiClient(); +{{#authMethods}}{{#isBasic}} +// Configure HTTP basic authorization: {{{name}}} +HttpBasicAuth {{{name}}} = (HttpBasicAuth) defaultClient.getAuthentication("{{{name}}}"); +{{{name}}}.setUsername("YOUR USERNAME"); +{{{name}}}.setPassword("YOUR PASSWORD");{{/isBasic}}{{#isApiKey}} +// Configure API key authorization: {{{name}}} +ApiKeyAuth {{{name}}} = (ApiKeyAuth) defaultClient.getAuthentication("{{{name}}}"); +{{{name}}}.setApiKey("YOUR API KEY"); +// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) +//{{{name}}}.setApiKeyPrefix("Token");{{/isApiKey}}{{#isOAuth}} +// Configure OAuth2 access token for authorization: {{{name}}} +OAuth {{{name}}} = (OAuth) defaultClient.getAuthentication("{{{name}}}"); +{{{name}}}.setAccessToken("YOUR ACCESS TOKEN");{{/isOAuth}} +{{/authMethods}} +{{/hasAuthMethods}} + +{{{classname}}} apiInstance = new {{{classname}}}(); +{{#allParams}} +{{{dataType}}} {{{paramName}}} = {{{example}}}; // {{{dataType}}} | {{{description}}} +{{/allParams}} +try { + {{#returnType}}{{{returnType}}} result = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}} + System.out.println(result);{{/returnType}} +} catch (ApiException e) { + System.err.println("Exception when calling {{{classname}}}#{{{operationId}}}"); + e.printStackTrace(); +} +``` + +### Parameters +{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}} +Name | Type | Description | Notes +------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}} +{{#allParams}} **{{paramName}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}[**{{dataType}}**]({{baseType}}.md){{/isFile}}{{/isPrimitiveType}}| {{description}} |{{^required}} [optional]{{/required}}{{#defaultValue}} [default to {{defaultValue}}]{{/defaultValue}}{{#allowableValues}} [enum: {{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}} +{{/allParams}} + +### Return type + +{{#returnType}}{{#returnTypeIsPrimitive}}**{{returnType}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{returnType}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}null (empty response body){{/returnType}} + +### Authorization + +{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{name}}](../README.md#{{name}}){{^-last}}, {{/-last}}{{/authMethods}} + +### HTTP request headers + + - **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}} + - **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}} + +{{/operation}} +{{/operations}} diff --git a/generator/cybersource-java-template/api_test.mustache b/generator/cybersource-java-template/api_test.mustache new file mode 100644 index 000000000..1d95ac2ed --- /dev/null +++ b/generator/cybersource-java-template/api_test.mustache @@ -0,0 +1,45 @@ +{{>licenseInfo}} + +package {{package}}; + +import {{invokerPackage}}.ApiException; +{{#imports}}import {{import}}; +{{/imports}} +import org.junit.Test; +import org.junit.Ignore; + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +/** + * API tests for {{classname}} + */ +@Ignore +public class {{classname}}Test { + + private final {{classname}} api = new {{classname}}(); + + {{#operations}}{{#operation}} + /** + * {{summary}} + * + * {{notes}} + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void {{operationId}}Test() throws ApiException { + {{#allParams}} + {{{dataType}}} {{paramName}} = null; + {{/allParams}} + {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + + // TODO: test validations + } + {{/operation}}{{/operations}} +} diff --git a/generator/cybersource-java-template/auth/ApiKeyAuth.mustache b/generator/cybersource-java-template/auth/ApiKeyAuth.mustache new file mode 100644 index 000000000..5af060f11 --- /dev/null +++ b/generator/cybersource-java-template/auth/ApiKeyAuth.mustache @@ -0,0 +1,64 @@ +{{>licenseInfo}} + +package {{invokerPackage}}.auth; + +import {{invokerPackage}}.Pair; + +import java.util.Map; +import java.util.List; + +{{>generatedAnnotation}} +public class ApiKeyAuth implements Authentication { + private final String location; + private final String paramName; + + private String apiKey; + private String apiKeyPrefix; + + public ApiKeyAuth(String location, String paramName) { + this.location = location; + this.paramName = paramName; + } + + public String getLocation() { + return location; + } + + public String getParamName() { + return paramName; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getApiKeyPrefix() { + return apiKeyPrefix; + } + + public void setApiKeyPrefix(String apiKeyPrefix) { + this.apiKeyPrefix = apiKeyPrefix; + } + + @Override + public void applyToParams(List queryParams, Map headerParams) { + if (apiKey == null) { + return; + } + String value; + if (apiKeyPrefix != null) { + value = apiKeyPrefix + " " + apiKey; + } else { + value = apiKey; + } + if ("query".equals(location)) { + queryParams.add(new Pair(paramName, value)); + } else if ("header".equals(location)) { + headerParams.put(paramName, value); + } + } +} diff --git a/generator/cybersource-java-template/auth/Authentication.mustache b/generator/cybersource-java-template/auth/Authentication.mustache new file mode 100644 index 000000000..26174fa3b --- /dev/null +++ b/generator/cybersource-java-template/auth/Authentication.mustache @@ -0,0 +1,18 @@ +{{>licenseInfo}} + +package {{invokerPackage}}.auth; + +import {{invokerPackage}}.Pair; + +import java.util.Map; +import java.util.List; + +public interface Authentication { + /** + * Apply authentication settings to header and query params. + * + * @param queryParams List of query parameters + * @param headerParams Map of header parameters + */ + void applyToParams(List queryParams, Map headerParams); +} diff --git a/generator/cybersource-java-template/auth/HttpBasicAuth.mustache b/generator/cybersource-java-template/auth/HttpBasicAuth.mustache new file mode 100644 index 000000000..015e042e1 --- /dev/null +++ b/generator/cybersource-java-template/auth/HttpBasicAuth.mustache @@ -0,0 +1,60 @@ +{{>licenseInfo}} + +package {{invokerPackage}}.auth; + +import {{invokerPackage}}.Pair; + +{{^java8}} +import com.migcomponents.migbase64.Base64; +{{/java8}} +{{#java8}} +import java.util.Base64; +import java.nio.charset.StandardCharsets; +{{/java8}} + +import java.util.Map; +import java.util.List; + +{{^java8}} +import java.io.UnsupportedEncodingException; +{{/java8}} + +{{>generatedAnnotation}} +public class HttpBasicAuth implements Authentication { + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public void applyToParams(List queryParams, Map headerParams) { + if (username == null && password == null) { + return; + } + String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); +{{^java8}} + try { + headerParams.put("Authorization", "Basic " + Base64.encodeToString(str.getBytes("UTF-8"), false)); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } +{{/java8}} +{{#java8}} + headerParams.put("Authorization", "Basic " + Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8))); +{{/java8}} + } +} diff --git a/generator/cybersource-java-template/auth/OAuth.mustache b/generator/cybersource-java-template/auth/OAuth.mustache new file mode 100644 index 000000000..ffc9923d1 --- /dev/null +++ b/generator/cybersource-java-template/auth/OAuth.mustache @@ -0,0 +1,28 @@ +{{>licenseInfo}} + +package {{invokerPackage}}.auth; + +import {{invokerPackage}}.Pair; + +import java.util.Map; +import java.util.List; + +{{>generatedAnnotation}} +public class OAuth implements Authentication { + private String accessToken; + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + @Override + public void applyToParams(List queryParams, Map headerParams) { + if (accessToken != null) { + headerParams.put("Authorization", "Bearer " + accessToken); + } + } +} diff --git a/generator/cybersource-java-template/auth/OAuthFlow.mustache b/generator/cybersource-java-template/auth/OAuthFlow.mustache new file mode 100644 index 000000000..002e9572f --- /dev/null +++ b/generator/cybersource-java-template/auth/OAuthFlow.mustache @@ -0,0 +1,7 @@ +{{>licenseInfo}} + +package {{invokerPackage}}.auth; + +public enum OAuthFlow { + accessCode, implicit, password, application +} diff --git a/generator/cybersource-java-template/beanValidation.mustache b/generator/cybersource-java-template/beanValidation.mustache new file mode 100644 index 000000000..7c347758d --- /dev/null +++ b/generator/cybersource-java-template/beanValidation.mustache @@ -0,0 +1,16 @@ +{{#required}} + @NotNull +{{/required}} +{{#isContainer}} +{{^isPrimitiveType}} +{{^isEnum}} + @Valid +{{/isEnum}} +{{/isPrimitiveType}} +{{/isContainer}} +{{#isNotContainer}} +{{^isPrimitiveType}} + @Valid +{{/isPrimitiveType}} +{{/isNotContainer}} +{{>beanValidationCore}} \ No newline at end of file diff --git a/generator/cybersource-java-template/beanValidationCore.mustache b/generator/cybersource-java-template/beanValidationCore.mustache new file mode 100644 index 000000000..db2a80d7b --- /dev/null +++ b/generator/cybersource-java-template/beanValidationCore.mustache @@ -0,0 +1,20 @@ +{{#pattern}} @Pattern(regexp="{{{pattern}}}"){{/pattern}}{{! +minLength && maxLength set +}}{{#minLength}}{{#maxLength}} @Size(min={{minLength}},max={{maxLength}}){{/maxLength}}{{/minLength}}{{! +minLength set, maxLength not +}}{{#minLength}}{{^maxLength}} @Size(min={{minLength}}){{/maxLength}}{{/minLength}}{{! +minLength not set, maxLength set +}}{{^minLength}}{{#maxLength}} @Size(max={{maxLength}}){{/maxLength}}{{/minLength}}{{! +@Size: minItems && maxItems set +}}{{#minItems}}{{#maxItems}} @Size(min={{minItems}},max={{maxItems}}){{/maxItems}}{{/minItems}}{{! +@Size: minItems set, maxItems not +}}{{#minItems}}{{^maxItems}} @Size(min={{minItems}}){{/maxItems}}{{/minItems}}{{! +@Size: minItems not set && maxItems set +}}{{^minItems}}{{#maxItems}} @Size(max={{maxItems}}){{/maxItems}}{{/minItems}}{{! +check for integer or long / all others=decimal type with @Decimal* +isInteger set +}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{! +isLong set +}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{! +Not Integer, not Long => we have a decimal value! +}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}} \ No newline at end of file diff --git a/generator/cybersource-java-template/beanValidationQueryParams.mustache b/generator/cybersource-java-template/beanValidationQueryParams.mustache new file mode 100644 index 000000000..f8eef8f94 --- /dev/null +++ b/generator/cybersource-java-template/beanValidationQueryParams.mustache @@ -0,0 +1 @@ +{{#required}} @NotNull{{/required}}{{>beanValidationCore}} \ No newline at end of file diff --git a/generator/cybersource-java-template/build.gradle.mustache b/generator/cybersource-java-template/build.gradle.mustache new file mode 100644 index 000000000..5f60c01b3 --- /dev/null +++ b/generator/cybersource-java-template/build.gradle.mustache @@ -0,0 +1,133 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 25 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + + {{#java8}} + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 + {{/java8}} + + install { + repositories.mavenInstaller { + pom.artifactId = '{{artifactId}}' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +ext { + swagger_annotations_version = "1.5.15" + jackson_version = "2.8.9" + jersey_version = "1.19.4" + jodatime_version = "2.9.9" + junit_version = "4.12" +} + +dependencies { + compile "io.swagger:swagger-annotations:$swagger_annotations_version" + compile "com.sun.jersey:jersey-client:$jersey_version" + compile "com.sun.jersey.contribs:jersey-multipart:$jersey_version" + compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version" + {{#java8}} + compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + {{/java8}} + {{^java8}} + compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + compile "joda-time:joda-time:$jodatime_version" + compile "com.brsanthu:migbase64:2.2" + {{/java8}} + testCompile "junit:junit:$junit_version" +} diff --git a/generator/cybersource-java-template/build.sbt.mustache b/generator/cybersource-java-template/build.sbt.mustache new file mode 100644 index 000000000..e69de29bb diff --git a/generator/cybersource-java-template/enum_outer_doc.mustache b/generator/cybersource-java-template/enum_outer_doc.mustache new file mode 100644 index 000000000..20c512aae --- /dev/null +++ b/generator/cybersource-java-template/enum_outer_doc.mustache @@ -0,0 +1,7 @@ +# {{classname}} + +## Enum + +{{#allowableValues}}{{#enumVars}} +* `{{name}}` (value: `{{{value}}}`) +{{/enumVars}}{{/allowableValues}} diff --git a/generator/cybersource-java-template/generatedAnnotation.mustache b/generator/cybersource-java-template/generatedAnnotation.mustache new file mode 100644 index 000000000..a47b6faa8 --- /dev/null +++ b/generator/cybersource-java-template/generatedAnnotation.mustache @@ -0,0 +1 @@ +{{^hideGenerationTimestamp}}@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}"){{/hideGenerationTimestamp}} \ No newline at end of file diff --git a/generator/cybersource-java-template/git_push.sh.mustache b/generator/cybersource-java-template/git_push.sh.mustache new file mode 100644 index 000000000..e153ce23e --- /dev/null +++ b/generator/cybersource-java-template/git_push.sh.mustache @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="{{{gitUserId}}}" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="{{{gitRepoId}}}" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="{{{releaseNote}}}" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/generator/cybersource-java-template/gitignore.mustache b/generator/cybersource-java-template/gitignore.mustache new file mode 100644 index 000000000..a530464af --- /dev/null +++ b/generator/cybersource-java-template/gitignore.mustache @@ -0,0 +1,21 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# exclude jar for gradle wrapper +!gradle/wrapper/*.jar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# build files +**/target +target +.gradle +build diff --git a/generator/cybersource-java-template/gradle-wrapper.jar b/generator/cybersource-java-template/gradle-wrapper.jar new file mode 100644 index 000000000..2c6137b87 Binary files /dev/null and b/generator/cybersource-java-template/gradle-wrapper.jar differ diff --git a/generator/cybersource-java-template/gradle-wrapper.properties.mustache b/generator/cybersource-java-template/gradle-wrapper.properties.mustache new file mode 100644 index 000000000..b7a364739 --- /dev/null +++ b/generator/cybersource-java-template/gradle-wrapper.properties.mustache @@ -0,0 +1,6 @@ +#Tue May 17 23:08:05 CST 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip diff --git a/generator/cybersource-java-template/gradle.properties.mustache b/generator/cybersource-java-template/gradle.properties.mustache new file mode 100644 index 000000000..05644f075 --- /dev/null +++ b/generator/cybersource-java-template/gradle.properties.mustache @@ -0,0 +1,2 @@ +# Uncomment to build for Android +#target = android \ No newline at end of file diff --git a/generator/cybersource-java-template/gradlew.bat.mustache b/generator/cybersource-java-template/gradlew.bat.mustache new file mode 100644 index 000000000..5f192121e --- /dev/null +++ b/generator/cybersource-java-template/gradlew.bat.mustache @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/generator/cybersource-java-template/gradlew.mustache b/generator/cybersource-java-template/gradlew.mustache new file mode 100644 index 000000000..9d82f7891 --- /dev/null +++ b/generator/cybersource-java-template/gradlew.mustache @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/generator/cybersource-java-template/libraries/feign/ApiClient.mustache b/generator/cybersource-java-template/libraries/feign/ApiClient.mustache new file mode 100644 index 000000000..e9cb564a6 --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/ApiClient.mustache @@ -0,0 +1,348 @@ +package {{invokerPackage}}; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +{{^java8}} +import com.fasterxml.jackson.datatype.joda.JodaModule; +{{/java8}} +{{#java8}} +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +{{/java8}} + +import feign.Feign; +import feign.RequestInterceptor; +import feign.form.FormEncoder; +import feign.jackson.JacksonDecoder; +import feign.jackson.JacksonEncoder; +import feign.slf4j.Slf4jLogger; +import {{invokerPackage}}.auth.*; +import {{invokerPackage}}.auth.OAuth.AccessTokenListener; + +{{>generatedAnnotation}} +public class ApiClient { + public interface Api {} + + protected ObjectMapper objectMapper; + private String basePath = "{{{basePath}}}"; + private Map apiAuthorizations; + private Feign.Builder feignBuilder; + + public ApiClient() { + objectMapper = createObjectMapper(); + apiAuthorizations = new LinkedHashMap(); + feignBuilder = Feign.builder() + .encoder(new FormEncoder(new JacksonEncoder(objectMapper))) + .decoder(new JacksonDecoder(objectMapper)) + .logger(new Slf4jLogger()); + } + + public ApiClient(String[] authNames) { + this(); + for(String authName : authNames) { + {{#hasAuthMethods}} + RequestInterceptor auth; + {{#authMethods}}if ("{{name}}".equals(authName)) { + {{#isBasic}} + auth = new HttpBasicAuth(); + {{/isBasic}} + {{#isApiKey}} + auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"); + {{/isApiKey}} + {{#isOAuth}} + auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}"); + {{/isOAuth}} + } else {{/authMethods}}{ + throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names"); + } + addAuthorization(authName, auth); + {{/hasAuthMethods}} + {{^hasAuthMethods}} + throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names"); + {{/hasAuthMethods}} + } + } + + /** + * Basic constructor for single auth name + * @param authName + */ + public ApiClient(String authName) { + this(new String[]{authName}); + } + + /** + * Helper constructor for single api key + * @param authName + * @param apiKey + */ + public ApiClient(String authName, String apiKey) { + this(authName); + this.setApiKey(apiKey); + } + + /** + * Helper constructor for single basic auth or password oauth2 + * @param authName + * @param username + * @param password + */ + public ApiClient(String authName, String username, String password) { + this(authName); + this.setCredentials(username, password); + } + + /** + * Helper constructor for single password oauth2 + * @param authName + * @param clientId + * @param secret + * @param username + * @param password + */ + public ApiClient(String authName, String clientId, String secret, String username, String password) { + this(authName); + this.getTokenEndPoint() + .setClientId(clientId) + .setClientSecret(secret) + .setUsername(username) + .setPassword(password); + } + + public String getBasePath() { + return basePath; + } + + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + public Map getApiAuthorizations() { + return apiAuthorizations; + } + + public void setApiAuthorizations(Map apiAuthorizations) { + this.apiAuthorizations = apiAuthorizations; + } + + public Feign.Builder getFeignBuilder() { + return feignBuilder; + } + + public ApiClient setFeignBuilder(Feign.Builder feignBuilder) { + this.feignBuilder = feignBuilder; + return this; + } + + private ObjectMapper createObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + objectMapper.disable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.setDateFormat(new RFC3339DateFormat()); + {{^java8}} + objectMapper.registerModule(new JodaModule()); + {{/java8}} + {{#java8}} + objectMapper.registerModule(new JavaTimeModule()); + {{/java8}} + return objectMapper; + } + + public ObjectMapper getObjectMapper(){ + return objectMapper; + } + + /** + * Creates a feign client for given API interface. + * + * Usage: + * ApiClient apiClient = new ApiClient(); + * apiClient.setBasePath("http://localhost:8080"); + * XYZApi api = apiClient.buildClient(XYZApi.class); + * XYZResponse response = api.someMethod(...); + * @param Type + * @param clientClass Client class + * @return The Client + */ + public T buildClient(Class clientClass) { + return feignBuilder.target(clientClass, basePath); + } + + /** + * Select the Accept header's value from the given accepts array: + * if JSON exists in the given array, use it; + * otherwise use all of them (joining into a string) + * + * @param accepts The accepts array to select from + * @return The Accept header to use. If the given array is empty, + * null will be returned (not to set the Accept header explicitly). + */ + public String selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) return null; + if (StringUtil.containsIgnoreCase(accepts, "application/json")) return "application/json"; + return StringUtil.join(accepts, ","); + } + + /** + * Select the Content-Type header's value from the given array: + * if JSON exists in the given array, use it; + * otherwise use the first one of the array. + * + * @param contentTypes The Content-Type array to select from + * @return The Content-Type header to use. If the given array is empty, + * JSON will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0) return "application/json"; + if (StringUtil.containsIgnoreCase(contentTypes, "application/json")) return "application/json"; + return contentTypes[0]; + } + + /** + * Helper method to configure the first api key found + * @param apiKey API key + */ + public void setApiKey(String apiKey) { + for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof ApiKeyAuth) { + ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization; + keyAuth.setApiKey(apiKey); + return ; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to configure the username/password for basic auth or password OAuth + * @param username Username + * @param password Password + */ + public void setCredentials(String username, String password) { + for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof HttpBasicAuth) { + HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization; + basicAuth.setCredentials(username, password); + return; + } + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.getTokenRequestBuilder().setUsername(username).setPassword(password); + return; + } + } + throw new RuntimeException("No Basic authentication or OAuth configured!"); + } + + /** + * Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one) + * @return Token request builder + */ + public TokenRequestBuilder getTokenEndPoint() { + for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + return oauth.getTokenRequestBuilder(); + } + } + return null; + } + + /** + * Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one) + * @return Authentication request builder + */ + public AuthenticationRequestBuilder getAuthorizationEndPoint() { + for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + return oauth.getAuthenticationRequestBuilder(); + } + } + return null; + } + + /** + * Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one) + * @param accessToken Access Token + * @param expiresIn Validity period in seconds + */ + public void setAccessToken(String accessToken, Long expiresIn) { + for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.setAccessToken(accessToken, expiresIn); + return; + } + } + } + + /** + * Helper method to configure the oauth accessCode/implicit flow parameters + * @param clientId Client ID + * @param clientSecret Client secret + * @param redirectURI Redirect URI + */ + public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) { + for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.getTokenRequestBuilder() + .setClientId(clientId) + .setClientSecret(clientSecret) + .setRedirectURI(redirectURI); + oauth.getAuthenticationRequestBuilder() + .setClientId(clientId) + .setRedirectURI(redirectURI); + return; + } + } + } + + /** + * Configures a listener which is notified when a new access token is received. + * @param accessTokenListener Acesss token listener + */ + public void registerAccessTokenListener(AccessTokenListener accessTokenListener) { + for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.registerAccessTokenListener(accessTokenListener); + return; + } + } + } + + /** + * Gets request interceptor based on authentication name + * @param authName Authentiation name + * @return Request Interceptor + */ + public RequestInterceptor getAuthorization(String authName) { + return apiAuthorizations.get(authName); + } + + /** + * Adds an authorization to be used by the client + * @param authName Authentication name + * @param authorization Request interceptor + */ + public void addAuthorization(String authName, RequestInterceptor authorization) { + if (apiAuthorizations.containsKey(authName)) { + throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations"); + } + apiAuthorizations.put(authName, authorization); + feignBuilder.requestInterceptor(authorization); + } + +} diff --git a/generator/cybersource-java-template/libraries/feign/EncodingUtils.mustache b/generator/cybersource-java-template/libraries/feign/EncodingUtils.mustache new file mode 100644 index 000000000..6f43e1c3c --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/EncodingUtils.mustache @@ -0,0 +1,86 @@ +package {{invokerPackage}}; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** +* Utilities to support Swagger encoding formats in Feign. +*/ +public final class EncodingUtils { + + /** + * Private constructor. Do not construct this class. + */ + private EncodingUtils() {} + + /** + *

Encodes a collection of query parameters according to the Swagger + * collection format.

+ * + *

Of the various collection formats defined by Swagger ("csv", "tsv", + * etc), Feign only natively supports "multi". This utility generates the + * other format types so it will be properly processed by Feign.

+ * + *

Note, as part of reformatting, it URL encodes the parameters as + * well.

+ * @param parameters The collection object to be formatted. This object will + * not be changed. + * @param collectionFormat The Swagger collection format (eg, "csv", "tsv", + * "pipes"). See the + * + * Swagger Spec for more details. + * @return An object that will be correctly formatted by Feign. + */ + public static Object encodeCollection(Collection parameters, + String collectionFormat) { + if (parameters == null) { + return parameters; + } + List stringValues = new ArrayList<>(parameters.size()); + for (Object parameter : parameters) { + // ignore null values (same behavior as Feign) + if (parameter != null) { + stringValues.add(encode(parameter)); + } + } + // Feign natively handles single-element lists and the "multi" format. + if (stringValues.size() < 2 || "multi".equals(collectionFormat)) { + return stringValues; + } + // Otherwise return a formatted String + String[] stringArray = stringValues.toArray(new String[0]); + switch (collectionFormat) { + case "csv": + default: + return StringUtil.join(stringArray, ","); + case "ssv": + return StringUtil.join(stringArray, " "); + case "tsv": + return StringUtil.join(stringArray, "\t"); + case "pipes": + return StringUtil.join(stringArray, "|"); + } + } + + /** + * URL encode a single query parameter. + * @param parameter The query parameter to encode. This object will not be + * changed. + * @return The URL encoded string representation of the parameter. If the + * parameter is null, returns null. + */ + public static String encode(Object parameter) { + if (parameter == null) { + return null; + } + try { + return URLEncoder.encode(parameter.toString(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } +} diff --git a/generator/cybersource-java-template/libraries/feign/ParamExpander.mustache b/generator/cybersource-java-template/libraries/feign/ParamExpander.mustache new file mode 100644 index 000000000..2f5095d00 --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/ParamExpander.mustache @@ -0,0 +1,22 @@ +package {{invokerPackage}}; + +import feign.Param; + +import java.text.DateFormat; +import java.util.Date; + +/** + * Param Expander to convert {@link Date} to RFC3339 + */ +public class ParamExpander implements Param.Expander { + + private static final DateFormat dateformat = new RFC3339DateFormat(); + + @Override + public String expand(Object value) { + if (value instanceof Date) { + return dateformat.format(value); + } + return value.toString(); + } +} diff --git a/generator/cybersource-java-template/libraries/feign/README.mustache b/generator/cybersource-java-template/libraries/feign/README.mustache new file mode 100644 index 000000000..56560172e --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/README.mustache @@ -0,0 +1,43 @@ +# {{artifactId}} + +## Requirements + +Building the API client library requires [Maven](https://maven.apache.org/) to be installed. + +## Installation & Usage + +To install the API client library to your local Maven repository, simply execute: + +```shell +mvn install +``` + +To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: + +```shell +mvn deploy +``` + +Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information. + +After the client library is installed/deployed, you can use it in your Maven project by adding the following to your *pom.xml*: + +```xml + + {{groupId}} + {{artifactId}} + {{artifactVersion}} + compile + + +``` + +## Recommendation + +It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. + +## Author + +{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}} +{{/hasMore}}{{/apis}}{{/apiInfo}} + diff --git a/generator/cybersource-java-template/libraries/feign/api.mustache b/generator/cybersource-java-template/libraries/feign/api.mustache new file mode 100644 index 000000000..67a772a87 --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/api.mustache @@ -0,0 +1,97 @@ +package {{package}}; + +import {{invokerPackage}}.ApiClient; +import {{invokerPackage}}.EncodingUtils; +{{#legacyDates}} +import {{invokerPackage}}.ParamExpander; +{{/legacyDates}} + +{{#imports}}import {{import}}; +{{/imports}} + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} +import feign.*; + +{{>generatedAnnotation}} +public interface {{classname}} extends ApiClient.Api { + +{{#operations}}{{#operation}} + /** + * {{summary}} + * {{notes}} +{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} +{{/allParams}} +{{#returnType}} + * @return {{returnType}} +{{/returnType}} + */ + @RequestLine("{{httpMethod}} {{{path}}}{{#hasQueryParams}}?{{/hasQueryParams}}{{#queryParams}}{{baseName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}") + @Headers({ + "Content-Type: {{vendorExtensions.x-contentType}}", + "Accept: {{vendorExtensions.x-accepts}}",{{#headerParams}} + "{{baseName}}: {{=<% %>=}}{<%paramName%>}<%={{ }}=%>"{{#hasMore}}, + {{/hasMore}}{{/headerParams}} + }) + {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{^isBodyParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isBodyParam}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + {{#hasQueryParams}} + + /** + * {{summary}} + * {{notes}} + * Note, this is equivalent to the other {{operationId}} method, + * but with the query parameters collected into a single Map parameter. This + * is convenient for services with optional query parameters, especially when + * used with the {@link {{operationIdCamelCase}}QueryParams} class that allows for + * building up this map in a fluent style. + {{#allParams}} + {{^isQueryParam}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} + {{/isQueryParam}} + {{/allParams}} + * @param queryParams Map of query parameters as name-value pairs + *

The following elements may be specified in the query map:

+ *
    + {{#queryParams}} + *
  • {{paramName}} - {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
  • + {{/queryParams}} + *
+ {{#returnType}} + * @return {{returnType}} + {{/returnType}} + */ + @RequestLine("{{httpMethod}} {{{path}}}?{{#queryParams}}{{baseName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}") + @Headers({ + "Content-Type: {{vendorExtensions.x-contentType}}", + "Accept: {{vendorExtensions.x-accepts}}",{{#headerParams}} + "{{baseName}}: {{=<% %>=}}{<%paramName%>}<%={{ }}=%>"{{#hasMore}}, + {{/hasMore}}{{/headerParams}} + }) + {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{^isQueryParam}}{{^isBodyParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isBodyParam}}{{{dataType}}} {{paramName}}, {{/isQueryParam}}{{/allParams}}@QueryMap(encoded=true) Map queryParams); + + /** + * A convenience class for generating query parameters for the + * {{operationId}} method in a fluent style. + */ + public static class {{operationIdCamelCase}}QueryParams extends HashMap { + {{#queryParams}} + public {{operationIdCamelCase}}QueryParams {{paramName}}(final {{{dataType}}} value) { + {{#collectionFormat}} + put("{{baseName}}", EncodingUtils.encodeCollection(value, "{{collectionFormat}}")); + {{/collectionFormat}} + {{^collectionFormat}} + put("{{baseName}}", EncodingUtils.encode(value)); + {{/collectionFormat}} + return this; + } + {{/queryParams}} + } + {{/hasQueryParams}} + {{/operation}} +{{/operations}} +} diff --git a/generator/cybersource-java-template/libraries/feign/api_test.mustache b/generator/cybersource-java-template/libraries/feign/api_test.mustache new file mode 100644 index 000000000..bcc14a987 --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/api_test.mustache @@ -0,0 +1,70 @@ +package {{package}}; + +import {{invokerPackage}}.ApiClient; +{{#imports}}import {{import}}; +{{/imports}} +import org.junit.Before; +import org.junit.Test; + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +/** + * API tests for {{classname}} + */ +public class {{classname}}Test { + + private {{classname}} api; + + @Before + public void setup() { + api = new ApiClient().buildClient({{classname}}.class); + } + + {{#operations}}{{#operation}} + /** + * {{summary}} + * + * {{notes}} + */ + @Test + public void {{operationId}}Test() { + {{#allParams}} + {{{dataType}}} {{paramName}} = null; + {{/allParams}} + // {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + + // TODO: test validations + } + + {{#hasQueryParams}} + /** + * {{summary}} + * + * {{notes}} + * + * This tests the overload of the method that uses a Map for query parameters instead of + * listing them out individually. + */ + @Test + public void {{operationId}}TestQueryMap() { + {{#allParams}} + {{^isQueryParam}} + {{{dataType}}} {{paramName}} = null; + {{/isQueryParam}} + {{/allParams}} + {{classname}}.{{operationIdCamelCase}}QueryParams queryParams = new {{classname}}.{{operationIdCamelCase}}QueryParams() + {{#queryParams}} + .{{paramName}}(null){{^hasMore}};{{/hasMore}} + {{/queryParams}} + // {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{^isQueryParam}}{{paramName}}, {{/isQueryParam}}{{/allParams}}queryParams); + + // TODO: test validations + } + {{/hasQueryParams}} + {{/operation}}{{/operations}} +} diff --git a/generator/cybersource-java-template/libraries/feign/auth/ApiKeyAuth.mustache b/generator/cybersource-java-template/libraries/feign/auth/ApiKeyAuth.mustache new file mode 100644 index 000000000..9982cd7fc --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/auth/ApiKeyAuth.mustache @@ -0,0 +1,41 @@ +package {{invokerPackage}}.auth; + +import feign.RequestInterceptor; +import feign.RequestTemplate; + +public class ApiKeyAuth implements RequestInterceptor { + private final String location; + private final String paramName; + + private String apiKey; + + public ApiKeyAuth(String location, String paramName) { + this.location = location; + this.paramName = paramName; + } + + public String getLocation() { + return location; + } + + public String getParamName() { + return paramName; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + @Override + public void apply(RequestTemplate template) { + if ("query".equals(location)) { + template.query(paramName, apiKey); + } else if ("header".equals(location)) { + template.header(paramName, apiKey); + } + } +} diff --git a/generator/cybersource-java-template/libraries/feign/auth/HttpBasicAuth.mustache b/generator/cybersource-java-template/libraries/feign/auth/HttpBasicAuth.mustache new file mode 100644 index 000000000..2b1acb8ff --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/auth/HttpBasicAuth.mustache @@ -0,0 +1,41 @@ +package {{invokerPackage}}.auth; + +import feign.RequestInterceptor; +import feign.RequestTemplate; +import feign.auth.BasicAuthRequestInterceptor; + +/** + * An interceptor that adds the request header needed to use HTTP basic authentication. + */ +public class HttpBasicAuth implements RequestInterceptor { + + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setCredentials(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + public void apply(RequestTemplate template) { + RequestInterceptor requestInterceptor = new BasicAuthRequestInterceptor(username, password); + requestInterceptor.apply(template); + } +} diff --git a/generator/cybersource-java-template/libraries/feign/auth/OAuth.mustache b/generator/cybersource-java-template/libraries/feign/auth/OAuth.mustache new file mode 100644 index 000000000..1df88d403 --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/auth/OAuth.mustache @@ -0,0 +1,197 @@ +package {{invokerPackage}}.auth; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.oltu.oauth2.client.HttpClient; +import org.apache.oltu.oauth2.client.OAuthClient; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; +import org.apache.oltu.oauth2.client.response.OAuthClientResponse; +import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory; +import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse; +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; +import org.apache.oltu.oauth2.common.exception.OAuthSystemException; +import org.apache.oltu.oauth2.common.message.types.GrantType; +import org.apache.oltu.oauth2.common.token.BasicOAuthToken; + +import feign.Client; +import feign.Request.Options; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import feign.Response; +import feign.RetryableException; +import feign.Util; +import {{invokerPackage}}.StringUtil; + + +public class OAuth implements RequestInterceptor { + + static final int MILLIS_PER_SECOND = 1000; + + public interface AccessTokenListener { + void notify(BasicOAuthToken token); + } + + private volatile String accessToken; + private Long expirationTimeMillis; + private OAuthClient oauthClient; + private TokenRequestBuilder tokenRequestBuilder; + private AuthenticationRequestBuilder authenticationRequestBuilder; + private AccessTokenListener accessTokenListener; + + public OAuth(Client client, TokenRequestBuilder requestBuilder) { + this.oauthClient = new OAuthClient(new OAuthFeignClient(client)); + this.tokenRequestBuilder = requestBuilder; + } + + public OAuth(Client client, OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) { + this(client, OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes)); + + switch(flow) { + case accessCode: + case implicit: + tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE); + break; + case password: + tokenRequestBuilder.setGrantType(GrantType.PASSWORD); + break; + case application: + tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS); + break; + default: + break; + } + authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl); + } + + public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) { + this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes); + } + + @Override + public void apply(RequestTemplate template) { + // If the request already have an authorization (eg. Basic auth), do nothing + if (template.headers().containsKey("Authorization")) { + return; + } + // If first time, get the token + if (expirationTimeMillis == null || System.currentTimeMillis() >= expirationTimeMillis) { + updateAccessToken(); + } + if (getAccessToken() != null) { + template.header("Authorization", "Bearer " + getAccessToken()); + } + } + + public synchronized void updateAccessToken() { + OAuthJSONAccessTokenResponse accessTokenResponse; + try { + accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage()); + } catch (Exception e) { + throw new RetryableException(e.getMessage(), e,null); + } + if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) { + setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn()); + if (accessTokenListener != null) { + accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken()); + } + } + } + + public synchronized void registerAccessTokenListener(AccessTokenListener accessTokenListener) { + this.accessTokenListener = accessTokenListener; + } + + public synchronized String getAccessToken() { + return accessToken; + } + + public synchronized void setAccessToken(String accessToken, Long expiresIn) { + this.accessToken = accessToken; + this.expirationTimeMillis = System.currentTimeMillis() + expiresIn * MILLIS_PER_SECOND; + } + + public TokenRequestBuilder getTokenRequestBuilder() { + return tokenRequestBuilder; + } + + public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) { + this.tokenRequestBuilder = tokenRequestBuilder; + } + + public AuthenticationRequestBuilder getAuthenticationRequestBuilder() { + return authenticationRequestBuilder; + } + + public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) { + this.authenticationRequestBuilder = authenticationRequestBuilder; + } + + public OAuthClient getOauthClient() { + return oauthClient; + } + + public void setOauthClient(OAuthClient oauthClient) { + this.oauthClient = oauthClient; + } + + public void setOauthClient(Client client) { + this.oauthClient = new OAuthClient( new OAuthFeignClient(client)); + } + + public static class OAuthFeignClient implements HttpClient { + + private Client client; + + public OAuthFeignClient() { + this.client = new Client.Default(null, null); + } + + public OAuthFeignClient(Client client) { + this.client = client; + } + + public T execute(OAuthClientRequest request, Map headers, + String requestMethod, Class responseClass) + throws OAuthSystemException, OAuthProblemException { + + RequestTemplate req = new RequestTemplate() + .append(request.getLocationUri()) + .method(requestMethod) + .body(request.getBody()); + + for (Entry entry : headers.entrySet()) { + req.header(entry.getKey(), entry.getValue()); + } + Response feignResponse; + String body = ""; + try { + feignResponse = client.execute(req.request(), new Options()); + body = Util.toString(feignResponse.body().asReader()); + } catch (IOException e) { + throw new OAuthSystemException(e); + } + + String contentType = null; + Collection contentTypeHeader = feignResponse.headers().get("Content-Type"); + if(contentTypeHeader != null) { + contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";"); + } + + return OAuthClientResponseFactory.createCustomResponse( + body, + contentType, + feignResponse.status(), + responseClass + ); + } + + public void shutdown() { + // Nothing to do here + } + } +} diff --git a/generator/cybersource-java-template/libraries/feign/build.gradle.mustache b/generator/cybersource-java-template/libraries/feign/build.gradle.mustache new file mode 100644 index 000000000..51ac6819f --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/build.gradle.mustache @@ -0,0 +1,124 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 25 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + + sourceCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} + targetCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} + + install { + repositories.mavenInstaller { + pom.artifactId = '{{artifactId}}' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +ext { + swagger_annotations_version = "1.5.9" + jackson_version = "2.8.7" + feign_version = "9.4.0" + feign_form_version = "2.1.0" + junit_version = "4.12" + oltu_version = "1.0.1" +} + +dependencies { + compile "io.swagger:swagger-annotations:$swagger_annotations_version" + compile "com.netflix.feign:feign-core:$feign_version" + compile "com.netflix.feign:feign-jackson:$feign_version" + compile "com.netflix.feign:feign-slf4j:$feign_version" + compile "io.github.openfeign.form:feign-form:$feign_form_version" + compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + compile "com.fasterxml.jackson.datatype:jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}:$jackson_version" + compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version" + compile "com.brsanthu:migbase64:2.2" + testCompile "junit:junit:$junit_version" +} diff --git a/generator/cybersource-java-template/libraries/feign/build.sbt.mustache b/generator/cybersource-java-template/libraries/feign/build.sbt.mustache new file mode 100644 index 000000000..c2d771961 --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/build.sbt.mustache @@ -0,0 +1,26 @@ +lazy val root = (project in file(".")). + settings( + organization := "{{groupId}}", + name := "{{artifactId}}", + version := "{{artifactVersion}}", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + "io.swagger" % "swagger-annotations" % "1.5.9" % "compile", + "com.netflix.feign" % "feign-core" % "9.4.0" % "compile", + "com.netflix.feign" % "feign-jackson" % "9.4.0" % "compile", + "com.netflix.feign" % "feign-slf4j" % "9.4.0" % "compile", + "io.github.openfeign.form" % "feign-form" % "2.1.0" % "compile", + "com.fasterxml.jackson.core" % "jackson-core" % "2.8.7" % "compile", + "com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.7" % "compile", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.8.7" % "compile", + "com.fasterxml.jackson.datatype" % "jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}" % "2.8.7" % "compile", + "org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile", + "com.brsanthu" % "migbase64" % "2.2" % "compile", + "junit" % "junit" % "4.12" % "test", + "com.novocode" % "junit-interface" % "0.10" % "test" + ) + ) diff --git a/generator/cybersource-java-template/libraries/feign/pom.mustache b/generator/cybersource-java-template/libraries/feign/pom.mustache new file mode 100644 index 000000000..20d8f9b88 --- /dev/null +++ b/generator/cybersource-java-template/libraries/feign/pom.mustache @@ -0,0 +1,268 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + 2.2.0 + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-core-version} + + + + + io.github.openfeign + feign-core + ${feign-version} + + + io.github.openfeign + feign-jackson + ${feign-version} + + + io.github.openfeign + feign-slf4j + ${feign-version} + + + io.github.openfeign.form + feign-form + ${feign-form-version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + {{#withXml}} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson-version} + + + {{/withXml}} + + com.fasterxml.jackson.datatype + jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}} + ${jackson-version} + + + org.apache.oltu.oauth2 + org.apache.oltu.oauth2.client + ${oltu-version} + + + + + junit + junit + ${junit-version} + test + + + com.squareup.okhttp3 + mockwebserver + 3.6.0 + test + + + org.assertj + assertj-core + 1.7.1 + test + + + + {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + ${java.version} + ${java.version} + 1.5.15 + 9.4.0 + 2.1.0 + 2.8.9 + 4.12 + 1.0.0 + 1.0.1 + + diff --git a/generator/cybersource-java-template/libraries/jersey2/ApiClient.mustache b/generator/cybersource-java-template/libraries/jersey2/ApiClient.mustache new file mode 100644 index 000000000..53fdcb989 --- /dev/null +++ b/generator/cybersource-java-template/libraries/jersey2/ApiClient.mustache @@ -0,0 +1,779 @@ +package {{invokerPackage}}; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.filter.LoggingFilter; +import org.glassfish.jersey.jackson.JacksonFeature; +import org.glassfish.jersey.media.multipart.FormDataBodyPart; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.MultiPart; +import org.glassfish.jersey.media.multipart.MultiPartFeature; + +import java.io.IOException; +import java.io.InputStream; + +{{^supportJava6}} +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +{{/supportJava6}} +{{#supportJava6}} +import org.apache.commons.io.FileUtils; +{{/supportJava6}} +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Date; +import java.util.TimeZone; + +import java.net.URLEncoder; + +import java.io.File; +import java.io.UnsupportedEncodingException; + +import java.text.DateFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import {{invokerPackage}}.auth.Authentication; +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; + +{{>generatedAnnotation}} +public class ApiClient { + private Map defaultHeaderMap = new HashMap(); + private String basePath = "{{{basePath}}}"; + private boolean debugging = false; + private int connectionTimeout = 0; + + private Client httpClient; + private JSON json; + private String tempFolderPath = null; + + private Map authentications; + + private int statusCode; + private Map> responseHeaders; + + private DateFormat dateFormat; + + public ApiClient() { + json = new JSON(); + httpClient = buildHttpClient(debugging); + + this.dateFormat = new RFC3339DateFormat(); + + // Set default User-Agent. + setUserAgent("{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}Swagger-Codegen/{{{artifactVersion}}}/java{{/httpUserAgent}}"); + + // Setup authentications (key: authentication name, value: authentication). + authentications = new HashMap();{{#authMethods}}{{#isBasic}} + authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}} + authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}} + authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}} + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + /** + * Gets the JSON instance to do JSON serialization and deserialization. + * @return JSON + */ + public JSON getJSON() { + return json; + } + + public Client getHttpClient() { + return httpClient; + } + + public ApiClient setHttpClient(Client httpClient) { + this.httpClient = httpClient; + return this; + } + + public String getBasePath() { + return basePath; + } + + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Gets the status code of the previous request + * @return Status code + */ + public int getStatusCode() { + return statusCode; + } + + /** + * Gets the response headers of the previous request + * @return Response headers + */ + public Map> getResponseHeaders() { + return responseHeaders; + } + + /** + * Get authentications (key: authentication name, value: authentication). + * @return Map of authentication object + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + * @param username Username + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + * @param password Password + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + * @param apiKey API key + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + * @param apiKeyPrefix API key prefix + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set access token for the first OAuth2 authentication. + * @param accessToken Access token + */ + public void setAccessToken(String accessToken) { + for (Authentication auth : authentications.values()) { + if (auth instanceof OAuth) { + ((OAuth) auth).setAccessToken(accessToken); + return; + } + } + throw new RuntimeException("No OAuth2 authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + * @param userAgent Http user agent + * @return API client + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + * @return API client + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + * @return True if debugging is switched on + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + * @return API client + */ + public ApiClient setDebugging(boolean debugging) { + this.debugging = debugging; + // Rebuild HTTP Client according to the new "debugging" value. + this.httpClient = buildHttpClient(debugging); + return this; + } + + /** + * The path of temporary folder used to store downloaded files from endpoints + * with file response. The default value is null, i.e. using + * the system's default tempopary folder. + * + * @return Temp folder path + */ + public String getTempFolderPath() { + return tempFolderPath; + } + + /** + * Set temp folder path + * @param tempFolderPath Temp folder path + * @return API client + */ + public ApiClient setTempFolderPath(String tempFolderPath) { + this.tempFolderPath = tempFolderPath; + return this; + } + + /** + * Connect timeout (in milliseconds). + * @return Connection timeout + */ + public int getConnectTimeout() { + return connectionTimeout; + } + + /** + * Set the connect timeout (in milliseconds). + * A value of 0 means no timeout, otherwise values must be between 1 and + * {@link Integer#MAX_VALUE}. + * @param connectionTimeout Connection timeout in milliseconds + * @return API client + */ + public ApiClient setConnectTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout); + return this; + } + + /** + * Get the date format used to parse/format date parameters. + * @return Date format + */ + public DateFormat getDateFormat() { + return dateFormat; + } + + /** + * Set the date format used to parse/format date parameters. + * @param dateFormat Date format + * @return API client + */ + public ApiClient setDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + // also set the date format for model (de)serialization with Date properties + this.json.setDateFormat((DateFormat) dateFormat.clone()); + return this; + } + + /** + * Parse the given string into Date object. + * @param str String + * @return Date + */ + public Date parseDate(String str) { + try { + return dateFormat.parse(str); + } catch (java.text.ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * Format the given Date object into string. + * @param date Date + * @return Date in string format + */ + public String formatDate(Date date) { + return dateFormat.format(date); + } + + /** + * Format the given parameter object into string. + * @param param Object + * @return Object in string format + */ + public String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date) { + return formatDate((Date) param); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for(Object o : (Collection)param) { + if(b.length() > 0) { + b.append(','); + } + b.append(String.valueOf(o)); + } + return b.toString(); + } else { + return String.valueOf(param); + } + } + + /* + * Format to {@code Pair} objects. + * @param collectionFormat Collection format + * @param name Name + * @param value Value + * @return List of pairs + */ + public List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList(); + + // preconditions + if (name == null || name.isEmpty() || value == null) return params; + + Collection valueCollection; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); + return params; + } + + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format (default: csv) + String format = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); + + // create the params based on the collection format + if ("multi".equals(format)) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); + } + + return params; + } + + String delimiter = ","; + + if ("csv".equals(format)) { + delimiter = ","; + } else if ("ssv".equals(format)) { + delimiter = " "; + } else if ("tsv".equals(format)) { + delimiter = "\t"; + } else if ("pipes".equals(format)) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + + return params; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime MIME + * @return True if the MIME type is JSON + */ + public boolean isJsonMime(String mime) { + String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"; + return mime != null && (mime.matches(jsonMime) || mime.equalsIgnoreCase("application/json-patch+json")); + } + + /** + * Select the Accept header's value from the given accepts array: + * if JSON exists in the given array, use it; + * otherwise use all of them (joining into a string) + * + * @param accepts The accepts array to select from + * @return The Accept header to use. If the given array is empty, + * null will be returned (not to set the Accept header explicitly). + */ + public String selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) { + return null; + } + for (String accept : accepts) { + if (isJsonMime(accept)) { + return accept; + } + } + return StringUtil.join(accepts, ","); + } + + /** + * Select the Content-Type header's value from the given array: + * if JSON exists in the given array, use it; + * otherwise use the first one of the array. + * + * @param contentTypes The Content-Type array to select from + * @return The Content-Type header to use. If the given array is empty, + * JSON will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0) { + return "application/json"; + } + for (String contentType : contentTypes) { + if (isJsonMime(contentType)) { + return contentType; + } + } + return contentTypes[0]; + } + + /** + * Escape the given string to be used as URL query value. + * @param str String + * @return Escaped string + */ + public String escapeString(String str) { + try { + return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + /** + * Serialize the given Java object into string entity according the given + * Content-Type (only JSON is supported for now). + * @param obj Object + * @param formParams Form parameters + * @param contentType Context type + * @return Entity + * @throws ApiException API exception + */ + public Entity serialize(Object obj, Map formParams, String contentType) throws ApiException { + Entity entity; + if (contentType.startsWith("multipart/form-data")) { + MultiPart multiPart = new MultiPart(); + for (Entry param: formParams.entrySet()) { + if (param.getValue() instanceof File) { + File file = (File) param.getValue(); + FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()) + .fileName(file.getName()).size(file.length()).build(); + multiPart.bodyPart(new FormDataBodyPart(contentDisp, file, MediaType.APPLICATION_OCTET_STREAM_TYPE)); + } else { + FormDataContentDisposition contentDisp = FormDataContentDisposition.name(param.getKey()).build(); + multiPart.bodyPart(new FormDataBodyPart(contentDisp, parameterToString(param.getValue()))); + } + } + entity = Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA_TYPE); + } else if (contentType.startsWith("application/x-www-form-urlencoded")) { + Form form = new Form(); + for (Entry param: formParams.entrySet()) { + form.param(param.getKey(), parameterToString(param.getValue())); + } + entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE); + } else { + // We let jersey handle the serialization + entity = Entity.entity(obj, contentType); + } + return entity; + } + + /** + * Deserialize response body to Java object according to the Content-Type. + * @param Type + * @param response Response + * @param returnType Return type + * @return Deserialize object + * @throws ApiException API exception + */ + @SuppressWarnings("unchecked") + public T deserialize(Response response, GenericType returnType) throws ApiException { + if (response == null || returnType == null) { + return null; + } + + if ("byte[]".equals(returnType.toString())) { + // Handle binary response (byte array). + return (T) response.readEntity(byte[].class); + } else if (returnType.getRawType() == File.class) { + // Handle file downloading. + T file = (T) downloadFileFromResponse(response); + return file; + } + + String contentType = null; + List contentTypes = response.getHeaders().get("Content-Type"); + if (contentTypes != null && !contentTypes.isEmpty()) + contentType = String.valueOf(contentTypes.get(0)); + if (contentType == null) + throw new ApiException(500, "missing Content-Type in response"); + + return response.readEntity(returnType); + } + + /** + * Download file from the given response. + * @param response Response + * @return File + * @throws ApiException If fail to read file content from response and write to disk + */ + public File downloadFileFromResponse(Response response) throws ApiException { + try { + File file = prepareDownloadFile(response); +{{^supportJava6}} + Files.copy(response.readEntity(InputStream.class), file.toPath(), StandardCopyOption.REPLACE_EXISTING); +{{/supportJava6}} +{{#supportJava6}} + // Java6 falls back to commons.io for file copying + FileUtils.copyToFile(response.readEntity(InputStream.class), file); +{{/supportJava6}} + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + public File prepareDownloadFile(Response response) throws IOException { + String filename = null; + String contentDisposition = (String) response.getHeaders().getFirst("Content-Disposition"); + if (contentDisposition != null && !"".equals(contentDisposition)) { + // Get filename from the Content-Disposition header. + Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + Matcher matcher = pattern.matcher(contentDisposition); + if (matcher.find()) + filename = matcher.group(1); + } + + String prefix; + String suffix = null; + if (filename == null) { + prefix = "download-"; + suffix = ""; + } else { + int pos = filename.lastIndexOf('.'); + if (pos == -1) { + prefix = filename + "-"; + } else { + prefix = filename.substring(0, pos) + "-"; + suffix = filename.substring(pos); + } + // File.createTempFile requires the prefix to be at least three characters long + if (prefix.length() < 3) + prefix = "download-"; + } + + if (tempFolderPath == null) + return File.createTempFile(prefix, suffix); + else + return File.createTempFile(prefix, suffix, new File(tempFolderPath)); + } + + /** + * Invoke API by sending HTTP request with the given options. + * + * @param Type + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "POST", "PUT", and "DELETE" + * @param queryParams The query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param accept The request's Accept header + * @param contentType The request's Content-Type header + * @param authNames The authentications to apply + * @param returnType The return type into which to deserialize the response + * @return The response body in type of string + * @throws ApiException API exception + */ + public T invokeAPI(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames, GenericType returnType) throws ApiException { + updateParamsForAuth(authNames, queryParams, headerParams); + + // Not using `.target(this.basePath).path(path)` below, + // to support (constant) query string in `path`, e.g. "/posts?draft=1" + WebTarget target = httpClient.target(this.basePath + path); + + if (queryParams != null) { + for (Pair queryParam : queryParams) { + if (queryParam.getValue() != null) { + target = target.queryParam(queryParam.getName(), queryParam.getValue()); + } + } + } + + Invocation.Builder invocationBuilder = target.request().accept(accept); + + for (Entry entry : headerParams.entrySet()) { + String value = entry.getValue(); + if (value != null) { + invocationBuilder = invocationBuilder.header(entry.getKey(), value); + } + } + + for (Entry entry : defaultHeaderMap.entrySet()) { + String key = entry.getKey(); + if (!headerParams.containsKey(key)) { + String value = entry.getValue(); + if (value != null) { + invocationBuilder = invocationBuilder.header(key, value); + } + } + } + + Entity entity = serialize(body, formParams, contentType); + + Response response = null; + + try { + if ("GET".equals(method)) { + response = invocationBuilder.get(); + } else if ("POST".equals(method)) { + response = invocationBuilder.post(entity); + } else if ("PUT".equals(method)) { + response = invocationBuilder.put(entity); + } else if ("DELETE".equals(method)) { + response = invocationBuilder.delete(); + } else if ("PATCH".equals(method)) { + response = invocationBuilder.header("X-HTTP-Method-Override", "PATCH").post(entity); + } else { + throw new ApiException(500, "unknown method type " + method); + } + + statusCode = response.getStatusInfo().getStatusCode(); + responseHeaders = buildResponseHeaders(response); + + if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) { + return null; + } else if (response.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL) { + if (returnType == null) + return null; + else + return deserialize(response, returnType); + } else { + String message = "error"; + String respBody = null; + if (response.hasEntity()) { + try { + respBody = String.valueOf(response.readEntity(String.class)); + message = respBody; + } catch (RuntimeException e) { + // e.printStackTrace(); + } + } + throw new ApiException( + response.getStatus(), + message, + buildResponseHeaders(response), + respBody); + } + } finally { + try { + response.close(); + } catch (Exception e) { + // it's not critical, since the response object is local in method invokeAPI; that's fine, just continue + } + } + } + + /** + * Build the Client used to make HTTP requests. + * @param debugging Debug setting + * @return Client + */ + private Client buildHttpClient(boolean debugging) { + final ClientConfig clientConfig = new ClientConfig(); + clientConfig.register(MultiPartFeature.class); + clientConfig.register(json); + clientConfig.register(JacksonFeature.class); + if (debugging) { + clientConfig.register(new LoggingFilter(java.util.logging.Logger.getLogger(LoggingFilter.class.getName()), true)); + } + return ClientBuilder.newClient(clientConfig); + } + + private Map> buildResponseHeaders(Response response) { + Map> responseHeaders = new HashMap>(); + for (Entry> entry: response.getHeaders().entrySet()) { + List values = entry.getValue(); + List headers = new ArrayList(); + for (Object o : values) { + headers.add(String.valueOf(o)); + } + responseHeaders.put(entry.getKey(), headers); + } + return responseHeaders; + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames The authentications to apply + */ + private void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); + auth.applyToParams(queryParams, headerParams); + } + } +} diff --git a/generator/cybersource-java-template/libraries/jersey2/JSON.mustache b/generator/cybersource-java-template/libraries/jersey2/JSON.mustache new file mode 100644 index 000000000..9d5ec1b07 --- /dev/null +++ b/generator/cybersource-java-template/libraries/jersey2/JSON.mustache @@ -0,0 +1,49 @@ +package {{invokerPackage}}; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.*; +{{#java8}} +import com.fasterxml.jackson.datatype.jsr310.*; +{{/java8}} +{{^java8}} +import com.fasterxml.jackson.datatype.joda.*; +{{/java8}} + +import java.text.DateFormat; + +import javax.ws.rs.ext.ContextResolver; + +{{>generatedAnnotation}} +public class JSON implements ContextResolver { + private ObjectMapper mapper; + + public JSON() { + mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + mapper.setDateFormat(new RFC3339DateFormat()); + {{#java8}} + mapper.registerModule(new JavaTimeModule()); + {{/java8}} + {{^java8}} + mapper.registerModule(new JodaModule()); + {{/java8}} + } + + /** + * Set the date format for JSON (de)serialization with Date properties. + * @param dateFormat Date format + */ + public void setDateFormat(DateFormat dateFormat) { + mapper.setDateFormat(dateFormat); + } + + @Override + public ObjectMapper getContext(Class type) { + return mapper; + } +} diff --git a/generator/cybersource-java-template/libraries/jersey2/api.mustache b/generator/cybersource-java-template/libraries/jersey2/api.mustache new file mode 100644 index 000000000..63df83ee2 --- /dev/null +++ b/generator/cybersource-java-template/libraries/jersey2/api.mustache @@ -0,0 +1,103 @@ +package {{package}}; + +import {{invokerPackage}}.ApiException; +import {{invokerPackage}}.ApiClient; +import {{invokerPackage}}.Configuration; +import {{invokerPackage}}.Pair; + +import javax.ws.rs.core.GenericType; + +{{#imports}}import {{import}}; +{{/imports}} + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +{{>generatedAnnotation}} +{{#operations}} +public class {{classname}} { + private ApiClient {{localVariablePrefix}}apiClient; + + public {{classname}}() { + this(Configuration.getDefaultApiClient()); + } + + public {{classname}}(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + public ApiClient getApiClient() { + return {{localVariablePrefix}}apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + {{#operation}} + /** + * {{summary}} + * {{notes}} + {{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} + {{/allParams}} + {{#returnType}} + * @return {{returnType}} + {{/returnType}} + * @throws ApiException if fails to make API call + */ + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException { + Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}; + {{#allParams}}{{#required}} + // verify the required parameter '{{paramName}}' is set + if ({{paramName}} == null) { + throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + } + {{/required}}{{/allParams}} + // create path and map variables + String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}} + .replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; + + // query params + {{javaUtilPrefix}}List {{localVariablePrefix}}localVarQueryParams = new {{javaUtilPrefix}}ArrayList(); + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarHeaderParams = new {{javaUtilPrefix}}HashMap(); + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarFormParams = new {{javaUtilPrefix}}HashMap(); + + {{#queryParams}} + {{localVariablePrefix}}localVarQueryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); + {{/queryParams}} + + {{#headerParams}}if ({{paramName}} != null) + {{localVariablePrefix}}localVarHeaderParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}})); + {{/headerParams}} + + {{#formParams}}if ({{paramName}} != null) + {{localVariablePrefix}}localVarFormParams.put("{{baseName}}", {{paramName}}); + {{/formParams}} + + final String[] {{localVariablePrefix}}localVarAccepts = { + {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} + }; + final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts); + + final String[] {{localVariablePrefix}}localVarContentTypes = { + {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} + }; + final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes); + + String[] {{localVariablePrefix}}localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; + + {{#returnType}} + GenericType<{{{returnType}}}> {{localVariablePrefix}}localVarReturnType = new GenericType<{{{returnType}}}>() {}; + return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, {{localVariablePrefix}}localVarReturnType); + {{/returnType}}{{^returnType}} + {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, null); + {{/returnType}} + } + {{/operation}} +} +{{/operations}} diff --git a/generator/cybersource-java-template/libraries/jersey2/build.gradle.mustache b/generator/cybersource-java-template/libraries/jersey2/build.gradle.mustache new file mode 100644 index 000000000..42db9488d --- /dev/null +++ b/generator/cybersource-java-template/libraries/jersey2/build.gradle.mustache @@ -0,0 +1,142 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 25 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + {{#java8}} + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 + {{/java8}} + + install { + repositories.mavenInstaller { + pom.artifactId = '{{artifactId}}' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +ext { + swagger_annotations_version = "1.5.15" + jackson_version = "2.8.9" + jersey_version = "2.25.1" + {{^java8}} + jodatime_version = "2.9.9" + {{/java8}} + {{#supportJava6}} + commons_io_version=2.5 + commons_lang3_version=3.6 + {{/supportJava6}} + junit_version = "4.12" +} + +dependencies { + compile "io.swagger:swagger-annotations:$swagger_annotations_version" + compile "org.glassfish.jersey.core:jersey-client:$jersey_version" + compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" + compile "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" + compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + {{#java8}} + compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + {{/java8}} + {{^java8}} + compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + compile "joda-time:joda-time:$jodatime_version" + compile "com.brsanthu:migbase64:2.2" + {{/java8}} + {{#supportJava6}} + compile "commons-io:commons-io:$commons_io_version" + compile "org.apache.commons:commons-lang3:$commons_lang3_version" + {{/supportJava6}} + testCompile "junit:junit:$junit_version" +} diff --git a/generator/cybersource-java-template/libraries/jersey2/build.sbt.mustache b/generator/cybersource-java-template/libraries/jersey2/build.sbt.mustache new file mode 100644 index 000000000..22d69f8ba --- /dev/null +++ b/generator/cybersource-java-template/libraries/jersey2/build.sbt.mustache @@ -0,0 +1,34 @@ +lazy val root = (project in file(".")). + settings( + organization := "{{groupId}}", + name := "{{artifactId}}", + version := "{{artifactVersion}}", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + "io.swagger" % "swagger-annotations" % "1.5.15", + "org.glassfish.jersey.core" % "jersey-client" % "2.25.1", + "org.glassfish.jersey.media" % "jersey-media-multipart" % "2.25.1", + "org.glassfish.jersey.media" % "jersey-media-json-jackson" % "2.25.1", + "com.fasterxml.jackson.core" % "jackson-core" % "2.8.9", + "com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.9", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.8.9", + {{#java8}} + "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.8.9", + {{/java8}} + {{^java8}} + "com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.8.9", + "joda-time" % "joda-time" % "2.9.9", + {{/java8}} + "com.brsanthu" % "migbase64" % "2.2", + {{#supportJava6}} + "org.apache.commons" % "commons-lang3" % "3.6", + "commons-io" % "commons-io" % "2.5", + {{/supportJava6}} + "junit" % "junit" % "4.12" % "test", + "com.novocode" % "junit-interface" % "0.10" % "test" + ) + ) diff --git a/generator/cybersource-java-template/libraries/jersey2/pom.mustache b/generator/cybersource-java-template/libraries/jersey2/pom.mustache new file mode 100644 index 000000000..b3c95a2f2 --- /dev/null +++ b/generator/cybersource-java-template/libraries/jersey2/pom.mustache @@ -0,0 +1,298 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + 2.2.0 + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + {{#java8}} + 1.8 + 1.8 + {{/java8}} + {{^java8}} + 1.7 + 1.7 + {{/java8}} + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-core-version} + + + + + org.glassfish.jersey.core + jersey-client + ${jersey-version} + + + org.glassfish.jersey.media + jersey-media-multipart + ${jersey-version} + + + org.glassfish.jersey.media + jersey-media-json-jackson + ${jersey-version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + {{#withXml}} + + + + org.glassfish.jersey.media + jersey-media-jaxb + ${jersey-version} + + + {{/withXml}} + {{#java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-version} + + {{/java8}} + {{^java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson-version} + + + joda-time + joda-time + ${jodatime-version} + + + + + com.brsanthu + migbase64 + 2.2 + + {{/java8}} + + {{#supportJava6}} + + org.apache.commons + commons-lang3 + ${commons_lang3_version} + + + + commons-io + commons-io + ${commons_io_version} + + {{/supportJava6}} + + + + junit + junit + ${junit-version} + test + + + + 1.5.15 + 2.25.1 + 2.8.9 + {{^java8}} + 2.9.9 + {{/java8}} + {{#supportJava6}} + 2.5 + 3.6 + {{/supportJava6}} + 1.0.0 + 4.12 + + diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/ApiCallback.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/ApiCallback.mustache new file mode 100644 index 000000000..4cc99a76e --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/ApiCallback.mustache @@ -0,0 +1,51 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import java.io.IOException; + +import java.util.Map; +import java.util.List; + +/** + * Callback for asynchronous API call. + * + * @param The return type + */ +public interface ApiCallback { + /** + * This is called when the API call fails. + * + * @param e The exception causing the failure + * @param statusCode Status code of the response if available, otherwise it would be 0 + * @param responseHeaders Headers of the response if available, otherwise it would be null + */ + void onFailure(ApiException e, int statusCode, Map> responseHeaders); + + /** + * This is called when the API call succeeded. + * + * @param result The result deserialized from response + * @param statusCode Status code of the response + * @param responseHeaders Headers of the response + */ + void onSuccess(T result, int statusCode, Map> responseHeaders); + + /** + * This is called when the API upload processing. + * + * @param bytesWritten bytes Written + * @param contentLength content length of request body + * @param done write end + */ + void onUploadProgress(long bytesWritten, long contentLength, boolean done); + + /** + * This is called when the API downlond processing. + * + * @param bytesRead bytes Read + * @param contentLength content lenngth of the response + * @param done Read end + */ + void onDownloadProgress(long bytesRead, long contentLength, boolean done); +} diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/ApiClient.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/ApiClient.mustache new file mode 100644 index 000000000..1346fcfc1 --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/ApiClient.mustache @@ -0,0 +1,1581 @@ +{{>licenseInfo}} +package {{invokerPackage}}; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Type; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import org.apache.logging.log4j.Logger; + +import com.cybersource.authsdk.core.Authorization; +import com.cybersource.authsdk.core.ConfigException; +import com.cybersource.authsdk.core.MerchantConfig; +import com.cybersource.authsdk.log.Log4j; +import com.cybersource.authsdk.payloaddigest.PayloadDigest; +import com.cybersource.authsdk.util.GlobalLabelParameters; +import com.cybersource.authsdk.util.PropertiesUtil; +import com.squareup.okhttp.Call; +import com.squareup.okhttp.Callback; +import com.squareup.okhttp.FormEncodingBuilder; +import com.squareup.okhttp.Headers; +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.MultipartBuilder; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.RequestBody; +import com.squareup.okhttp.Response; +import com.squareup.okhttp.internal.http.HttpMethod; +import com.squareup.okhttp.logging.HttpLoggingInterceptor; +import com.squareup.okhttp.logging.HttpLoggingInterceptor.Level; + +import Invokers.auth.ApiKeyAuth; +import Invokers.auth.Authentication; +import Invokers.auth.HttpBasicAuth; +import Invokers.auth.OAuth; +import okio.BufferedSink; +import okio.Okio; + +{{>generatedAnnotation}} +public class ApiClient { + public static final double JAVA_VERSION; + public static final boolean IS_ANDROID; + public static final int ANDROID_SDK_VERSION; + public static String responseCode; + public static String status; + public static String responseBody; + public static String respBody; + public static MerchantConfig merchantConfig; + + static { + JAVA_VERSION = Double.parseDouble(System.getProperty("java.specification.version")); + boolean isAndroid; + try { + Class.forName("android.app.Activity"); + isAndroid = true; + } catch (ClassNotFoundException e) { + isAndroid = false; + } + IS_ANDROID = isAndroid; + int sdkVersion = 0; + if (IS_ANDROID) { + try { + sdkVersion = Class.forName("android.os.Build$VERSION").getField("SDK_INT").getInt(null); + } catch (Exception e) { + try { + sdkVersion = Integer + .parseInt((String) Class.forName("android.os.Build$VERSION").getField("SDK").get(null)); + } catch (Exception e2) { + } + } + } + ANDROID_SDK_VERSION = sdkVersion; + } + + /** + * The datetime format to be used when lenientDatetimeFormat is + * enabled. + */ + public static final String LENIENT_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + + private String basePath = ""; + private boolean lenientOnJson = false; + private boolean debugging = false; + private Map defaultHeaderMap = new HashMap(); + private String tempFolderPath = null; + + private Map authentications; + + private DateFormat dateFormat; + private DateFormat datetimeFormat; + private boolean lenientDatetimeFormat; + private int dateLength; + + private InputStream sslCaCert; + private boolean verifyingSsl; + private KeyManager[] keyManagers; + + private OkHttpClient httpClient; + private JSON json; + + private HttpLoggingInterceptor loggingInterceptor; + + /* + * Constructor for ApiClient + */ + public ApiClient() { + httpClient = new OkHttpClient(); + + verifyingSsl = true; + + json = new JSON(this); + + /* + * Use RFC3339 format for date and datetime. See + * http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14 + */ + this.dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + // Always use UTC as the default time zone when dealing with date + // (without time). + this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + initDatetimeFormat(); + + // Be lenient on datetime formats when parsing datetime from string. + // See parseDatetime. + this.lenientDatetimeFormat = true; + + // Set default User-Agent. + setUserAgent("Swagger-Codegen/1.0.0/java"); + + // Setup authentications (key: authentication name, value: + // authentication). + authentications = new HashMap(); + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + public ApiClient(MerchantConfig merchantConfig) { + this.merchantConfig = merchantConfig; + + } + + /** + * Get base path + * + * @return Baes path + */ + public String getBasePath() { + return basePath; + } + + /** + * Set base path + * + * @param basePath + * Base path of the URL (e.g https://apitest.cybersource.com) + * @return An instance of OkHttpClient + */ + public ApiClient setBasePath(String basePath) { + this.basePath = this.basePath.concat(merchantConfig.getRequestHost()); + return this; + } + + /** + * Get HTTP client + * + * @return An instance of OkHttpClient + */ + public OkHttpClient getHttpClient() { + return httpClient; + } + + /** + * Set HTTP client + * + * @param httpClient + * An instance of OkHttpClient + * @return Api Client + */ + public ApiClient setHttpClient(OkHttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + /** + * Get JSON + * + * @return JSON object + */ + public JSON getJSON() { + return json; + } + + /** + * Set JSON + * + * @param json + * JSON object + * @return Api client + */ + public ApiClient setJSON(JSON json) { + this.json = json; + return this; + } + + /** + * True if isVerifyingSsl flag is on + * + * @return True if isVerifySsl flag is on + */ + public boolean isVerifyingSsl() { + return verifyingSsl; + } + + /** + * Configure whether to verify certificate and hostname when making https + * requests. Default to true. NOTE: Do NOT set to false in production code, + * otherwise you would face multiple types of cryptographic attacks. + * + * @param verifyingSsl + * True to verify TLS/SSL connection + * @return ApiClient + */ + public ApiClient setVerifyingSsl(boolean verifyingSsl) { + this.verifyingSsl = verifyingSsl; + applySslSettings(); + return this; + } + + /** + * Get SSL CA cert. + * + * @return Input stream to the SSL CA cert + */ + public InputStream getSslCaCert() { + return sslCaCert; + } + + /** + * Configure the CA certificate to be trusted when making https requests. + * Use null to reset to default. + * + * @param sslCaCert + * input stream for SSL CA cert + * @return ApiClient + */ + public ApiClient setSslCaCert(InputStream sslCaCert) { + this.sslCaCert = sslCaCert; + applySslSettings(); + return this; + } + + public KeyManager[] getKeyManagers() { + return keyManagers; + } + + /** + * Configure client keys to use for authorization in an SSL session. Use + * null to reset to default. + * + * @param managers + * The KeyManagers to use + * @return ApiClient + */ + public ApiClient setKeyManagers(KeyManager[] managers) { + this.keyManagers = managers; + applySslSettings(); + return this; + } + + public DateFormat getDateFormat() { + return dateFormat; + } + + public ApiClient setDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + this.dateLength = this.dateFormat.format(new Date()).length(); + return this; + } + + public DateFormat getDatetimeFormat() { + return datetimeFormat; + } + + public ApiClient setDatetimeFormat(DateFormat datetimeFormat) { + this.datetimeFormat = datetimeFormat; + return this; + } + + /** + * Whether to allow various ISO 8601 datetime formats when parsing a + * datetime string. + * + * @see #parseDatetime(String) + * @return True if lenientDatetimeFormat flag is set to true + */ + public boolean isLenientDatetimeFormat() { + return lenientDatetimeFormat; + } + + public ApiClient setLenientDatetimeFormat(boolean lenientDatetimeFormat) { + this.lenientDatetimeFormat = lenientDatetimeFormat; + return this; + } + + /** + * Parse the given date string into Date object. The default + * dateFormat supports these ISO 8601 date formats: 2015-08-16 + * 2015-8-16 + * + * @param str + * String to be parsed + * @return Date + */ + public Date parseDate(String str) { + if (str == null) + return null; + try { + return dateFormat.parse(str); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * Parse the given datetime string into Date object. When + * lenientDatetimeFormat is enabled, the following ISO 8601 datetime formats + * are supported: 2015-08-16T08:20:05Z 2015-8-16T8:20:05Z + * 2015-08-16T08:20:05+00:00 2015-08-16T08:20:05+0000 + * 2015-08-16T08:20:05.376Z 2015-08-16T08:20:05.376+00:00 + * 2015-08-16T08:20:05.376+00 Note: The 3-digit milli-seconds is optional. + * Time zone is required and can be in one of these formats: Z (same with + * +0000) +08:00 (same with +0800) -02 (same with -0200) -0200 + * + * @see ISO 8601 + * @param str + * Date time string to be parsed + * @return Date representation of the string + */ + public Date parseDatetime(String str) { + if (str == null) + return null; + + DateFormat format; + if (lenientDatetimeFormat) { + /* + * When lenientDatetimeFormat is enabled, normalize the date string + * into LENIENT_DATETIME_FORMAT to support various + * formats defined by ISO 8601. + */ + // normalize time zone + // trailing "Z": 2015-08-16T08:20:05Z => 2015-08-16T08:20:05+0000 + str = str.replaceAll("[zZ]\\z", "+0000"); + // remove colon in time zone: 2015-08-16T08:20:05+00:00 => + // 2015-08-16T08:20:05+0000 + str = str.replaceAll("([+-]\\d{2}):(\\d{2})\\z", "$1$2"); + // expand time zone: 2015-08-16T08:20:05+00 => + // 2015-08-16T08:20:05+0000 + str = str.replaceAll("([+-]\\d{2})\\z", "$100"); + // add milliseconds when missing + // 2015-08-16T08:20:05+0000 => 2015-08-16T08:20:05.000+0000 + str = str.replaceAll("(:\\d{1,2})([+-]\\d{4})\\z", "$1.000$2"); + format = new SimpleDateFormat(LENIENT_DATETIME_FORMAT); + } else { + format = this.datetimeFormat; + } + + try { + return format.parse(str); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + /* + * Parse date or date time in string format into Date object. + * + * @param str Date time string to be parsed + * + * @return Date representation of the string + */ + public Date parseDateOrDatetime(String str) { + if (str == null) + return null; + else if (str.length() <= dateLength) + return parseDate(str); + else + return parseDatetime(str); + } + + /** + * Format the given Date object into string (Date format). + * + * @param date + * Date object + * @return Formatted date in string representation + */ + public String formatDate(Date date) { + return dateFormat.format(date); + } + + /** + * Format the given Date object into string (Datetime format). + * + * @param date + * Date object + * @return Formatted datetime in string representation + */ + public String formatDatetime(Date date) { + return datetimeFormat.format(date); + } + + /** + * Get authentications (key: authentication name, value: authentication). + * + * @return Map of authentication objects + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName + * The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + * + * @param username + * Username + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + * + * @param password + * Password + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + * + * @param apiKey + * API key + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + * + * @param apiKeyPrefix + * API key prefix + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set access token for the first OAuth2 authentication. + * + * @param accessToken + * Access token + */ + public void setAccessToken(String accessToken) { + for (Authentication auth : authentications.values()) { + if (auth instanceof OAuth) { + ((OAuth) auth).setAccessToken(accessToken); + return; + } + } + throw new RuntimeException("No OAuth2 authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + * + * @param userAgent + * HTTP request's user agent + * @return ApiClient + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key + * The header's key + * @param value + * The header's value + * @return ApiClient + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * @see setLenient + * + * @return True if lenientOnJson is enabled, false otherwise. + */ + public boolean isLenientOnJson() { + return lenientOnJson; + } + + /** + * Set LenientOnJson + * + * @param lenient + * True to enable lenientOnJson + * @return ApiClient + */ + public ApiClient setLenientOnJson(boolean lenient) { + this.lenientOnJson = lenient; + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + * + * @return True if debugging is enabled, false otherwise. + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging + * To enable (true) or disable (false) debugging + * @return ApiClient + */ + public ApiClient setDebugging(boolean debugging) { + if (debugging != this.debugging) { + if (debugging) { + loggingInterceptor = new HttpLoggingInterceptor(); + loggingInterceptor.setLevel(Level.BODY); + httpClient.interceptors().add(loggingInterceptor); + } else { + httpClient.interceptors().remove(loggingInterceptor); + loggingInterceptor = null; + } + } + this.debugging = debugging; + return this; + } + + /** + * The path of temporary folder used to store downloaded files from + * endpoints with file response. The default value is null, + * i.e. using the system's default tempopary folder. + * + * @see createTempFile + * @return Temporary folder path + */ + public String getTempFolderPath() { + return tempFolderPath; + } + + /** + * Set the tempoaray folder path (for downloading files) + * + * @param tempFolderPath + * Temporary folder path + * @return ApiClient + */ + public ApiClient setTempFolderPath(String tempFolderPath) { + this.tempFolderPath = tempFolderPath; + return this; + } + + /** + * Get connection timeout (in milliseconds). + * + * @return Timeout in milliseconds + */ + public int getConnectTimeout() { + return httpClient.getConnectTimeout(); + } + + /** + * Sets the connect timeout (in milliseconds). A value of 0 means no + * timeout, otherwise values must be between 1 and + * + * @param connectionTimeout + * connection timeout in milliseconds + * @return Api client + */ + public ApiClient setConnectTimeout(int connectionTimeout) { + httpClient.setConnectTimeout(connectionTimeout, TimeUnit.MILLISECONDS); + return this; + } + + /** + * Format the given parameter object into string. + * + * @param param + * Parameter + * @return String representation of the parameter + */ + public String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date) { + return formatDatetime((Date) param); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for (Object o : (Collection) param) { + if (b.length() > 0) { + b.append(","); + } + b.append(String.valueOf(o)); + } + return b.toString(); + } else { + return String.valueOf(param); + } + } + + /** + * Format to {@code Pair} objects. + * + * @param collectionFormat + * collection format (e.g. csv, tsv) + * @param name + * Name + * @param value + * Value + * @return A list of Pair objects + */ + public List parameterToPairs(String collectionFormat, String name, Object value) { + List params = new ArrayList(); + + // preconditions + if (name == null || name.isEmpty() || value == null) + return params; + + Collection valueCollection = null; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); + return params; + } + + if (valueCollection.isEmpty()) { + return params; + } + + // get the collection format + collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: + // csv + + // create the params based on the collection format + if (collectionFormat.equals("multi")) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); + } + + return params; + } + + String delimiter = ","; + + if (collectionFormat.equals("csv")) { + delimiter = ","; + } else if (collectionFormat.equals("ssv")) { + delimiter = " "; + } else if (collectionFormat.equals("tsv")) { + delimiter = "\t"; + } else if (collectionFormat.equals("pipes")) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder(); + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + + return params; + } + + /** + * Sanitize filename by removing path. e.g. ../../sun.gif becomes sun.gif + * + * @param filename + * The filename to be sanitized + * @return The sanitized filename + */ + public String sanitizeFilename(String filename) { + return filename.replaceAll(".*[/\\\\]", ""); + } + + /** + * Check if the given MIME is a JSON MIME. JSON MIME examples: + * application/json application/json; charset=UTF8 APPLICATION/JSON + * application/vnd.company+json + * + * @param mime + * MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public boolean isJsonMime(String mime) { + String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"; + return mime != null && (mime.matches(jsonMime) || mime.equalsIgnoreCase("application/json-patch+json")); + } + + /** + * Select the Accept header's value from the given accepts array: if JSON + * exists in the given array, use it; otherwise use all of them (joining + * into a string) + * + * @param accepts + * The accepts array to select from + * @return The Accept header to use. If the given array is empty, null will + * be returned (not to set the Accept header explicitly). + */ + public String selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) { + return null; + } + for (String accept : accepts) { + if (isJsonMime(accept)) { + return accept; + } + } + return StringUtil.join(accepts, ","); + } + + /** + * Select the Content-Type header's value from the given array: if JSON + * exists in the given array, use it; otherwise use the first one of the + * array. + * + * @param contentTypes + * The Content-Type array to select from + * @return The Content-Type header to use. If the given array is empty, JSON + * will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0) { + return "application/json"; + } + for (String contentType : contentTypes) { + if (isJsonMime(contentType)) { + return contentType; + } + } + return contentTypes[0]; + } + + /** + * Escape the given string to be used as URL query value. + * + * @param str + * String to be escaped + * @return Escaped string + */ + public String escapeString(String str) { + try { + return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + /** + * Deserialize response body to Java object, according to the return type + * and the Content-Type response header. + * + * @param + * Type + * @param response + * HTTP response + * @param returnType + * The type of the Java object + * @return The deserialized Java object + * @throws ApiException + * If fail to deserialize response body, i.e. cannot read + * response body or the Content-Type of the response is not + * supported. + */ + @SuppressWarnings("unchecked") + public T deserialize(Response response, Type returnType) throws ApiException { + if (response == null /* || returnType == null */) { + return null; + } + if (returnType == null && response != null) { + try { + return (T) response.body().bytes(); + } catch (IOException e) { + throw new ApiException(e); + } + } else + + if ("byte[]".equals(returnType.toString())) { + // Handle binary response (byte array). + try { + return (T) response.body().bytes(); + } catch (IOException e) { + throw new ApiException(e); + } + } else if (returnType.equals(File.class)) { + // Handle file downloading. + return (T) downloadFileFromResponse(response); + } + + try { + if (response.body() != null) + respBody = response.body().string(); + else + respBody = null; + } catch (IOException e) { + throw new ApiException(e); + } + + if (respBody == null || "".equals(respBody)) { + return null; + } + + String contentType = response.headers().get("Content-Type"); + if (contentType == null) { + // ensuring a default content type + contentType = "application/json"; + } + if (isJsonMime(contentType)) { + return json.deserialize(respBody, returnType); + } else if (returnType.equals(String.class)) { + // Expecting string, return the raw response body. + return (T) respBody; + } else { + throw new ApiException("Content type \"" + contentType + "\" is not supported for type: " + returnType, + response.code(), response.headers().toMultimap(), respBody); + } + } + + /** + * Serialize the given Java object into request body according to the + * object's class and the request Content-Type. + * + * @param obj + * The Java object + * @param contentType + * The request Content-Type + * @return The serialized request body + * @throws ApiException + * If fail to serialize the given object + */ + public RequestBody serialize(Object obj, String contentType) throws ApiException { + if (obj instanceof byte[]) { + // Binary (byte array) body parameter support. + return RequestBody.create(MediaType.parse(contentType), (byte[]) obj); + } else if (obj instanceof File) { + // File body parameter support. + return RequestBody.create(MediaType.parse(contentType), (File) obj); + } else if (isJsonMime(contentType)) { + String content; + if (obj != null) { + content = json.serialize(obj); + } else { + content = null; + } + return RequestBody.create(MediaType.parse(contentType), content); + } else { + throw new ApiException("Content type \"" + contentType + "\" is not supported"); + } + } + + /** + * Download file from the given response. + * + * @param response + * An instance of the Response object + * @throws ApiException + * If fail to read file content from response and write to disk + * @return Downloaded file + */ + public File downloadFileFromResponse(Response response) throws ApiException { + try { + File file = prepareDownloadFile(response); + BufferedSink sink = Okio.buffer(Okio.sink(file)); + sink.writeAll(response.body().source()); + sink.close(); + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + * Prepare file for download + * + * @param response + * An instance of the Response object + * @throws IOException + * If fail to prepare file for download + * @return Prepared file for the download + */ + public File prepareDownloadFile(Response response) throws IOException { + String filename = null; + String contentDisposition = response.header("Content-Disposition"); + if (contentDisposition != null && !"".equals(contentDisposition)) { + // Get filename from the Content-Disposition header. + Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + Matcher matcher = pattern.matcher(contentDisposition); + if (matcher.find()) { + filename = sanitizeFilename(matcher.group(1)); + } + } + + String prefix = null; + String suffix = null; + if (filename == null) { + prefix = "download-"; + suffix = ""; + } else { + int pos = filename.lastIndexOf("."); + if (pos == -1) { + prefix = filename + "-"; + } else { + prefix = filename.substring(0, pos) + "-"; + suffix = filename.substring(pos); + } + // File.createTempFile requires the prefix to be at least three + // characters long + if (prefix.length() < 3) + prefix = "download-"; + } + + if (tempFolderPath == null) + return File.createTempFile(prefix, suffix); + else + return File.createTempFile(prefix, suffix, new File(tempFolderPath)); + } + + /** + * {@link #execute(Call, Type)} + * + * @param + * Type + * @param call + * An instance of the Call object + * @throws ApiException + * If fail to execute the call + * @return ApiResponse<T> + */ + public ApiResponse execute(Call call) throws ApiException { + return execute(call, null); + } + + /** + * Execute HTTP call and deserialize the HTTP response body into the given + * return type. + * + * @param returnType + * The return type used to deserialize HTTP response body + * @param + * The return type corresponding to (same with) returnType + * @param call + * Call + * @return ApiResponse object containing response status, headers and data, + * which is a Java object deserialized from response body and would + * be null when returnType is null. + * @throws ApiException + * If fail to execute the call + */ + public ApiResponse execute(Call call, Type returnType) throws ApiException { + try { + Response response = call.execute(); + responseCode = String.valueOf(response.code()); + status = response.message(); + String headerType = response.header("Content-Type"); + if (headerType != null) + if (headerType.equals("application/xml") || headerType.equals("text/csv") + || headerType.equals("application/pdf")) { + responseBody = response.body().string(); + } + if (!(responseCode.equals("200"))) { + if (!responseCode.equals("201")) { + System.out.println(response.body().string()); + } + } + T data = handleResponse(response, returnType); + if (headerType != null) + if (!headerType.equals("application/xml") && !headerType.equals("text/csv") + && !headerType.equals("application/pdf")) { + responseBody = response.toString(); + } + return new ApiResponse(response.code(), response.headers().toMultimap(), data); + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + * {@link #executeAsync(Call, Type, ApiCallback)} + * + * @param + * Type + * @param call + * An instance of the Call object + * @param callback + * ApiCallback<T> + */ + public void executeAsync(Call call, ApiCallback callback) { + executeAsync(call, null, callback); + } + + /** + * Execute HTTP call asynchronously. + * + * @see #execute(Call, Type) + * @param + * Type + * @param call + * The callback to be executed when the API call finishes + * @param returnType + * Return type + * @param callback + * ApiCallback + */ + @SuppressWarnings("unchecked") + public void executeAsync(Call call, final Type returnType, final ApiCallback callback) { + call.enqueue(new Callback() { + @Override + public void onFailure(Request request, IOException e) { + callback.onFailure(new ApiException(e), 0, null); + } + + @Override + public void onResponse(Response response) throws IOException { + T result; + try { + result = (T) handleResponse(response, returnType); + } catch (ApiException e) { + callback.onFailure(e, response.code(), response.headers().toMultimap()); + return; + } + callback.onSuccess(result, response.code(), response.headers().toMultimap()); + } + }); + } + + /** + * Handle the given response, return the deserialized object when the + * response is successful. + * + * @param + * Type + * @param response + * Response + * @param returnType + * Return type + * @throws ApiException + * If the response has a unsuccessful status code or fail to + * deserialize the response body + * @return Type + */ + public T handleResponse(Response response, Type returnType) throws ApiException { + if (response.isSuccessful()) { + if (/* returnType == null || */ response.code() == 204) { + // returning null if the returnType is not defined, + // or the status code is 204 (No Content) + if (response.body() != null) { + try { + response.body().close(); + } catch (IOException e) { + throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap()); + } + } + return null; + } else { + return deserialize(response, returnType); + } + } else { + String respBody = null; + if (response.body() != null) { + try { + respBody = response.body().string(); + System.out.println(respBody); + } catch (IOException e) { + throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap()); + } + } + throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody); + } + } + + /** + * Build HTTP call with the given options. + * + * @param path + * The sub-path of the HTTP URL + * @param method + * The request method, one of "GET", "HEAD", "OPTIONS", "POST", + * "PUT", "PATCH" and "DELETE" + * @param queryParams + * The query parameters + * @param body + * The request body object + * @param headerParams + * The header parameters + * @param formParams + * The form parameters + * @param authNames + * The authentications to apply + * @param progressRequestListener + * Progress request listener + * @return The HTTP call + * @throws ApiException + * If fail to serialize the request body object + */ + public Call buildCall(String path, String method, List queryParams, Object body, + Map headerParams, Map formParams, String[] authNames, + ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException { + callAuthenticationHeader(method, path, body, queryParams); + headerParams.putAll(defaultHeaderMap); + Request request = buildRequest(path, method, queryParams, body, headerParams, formParams, authNames, + progressRequestListener); + return httpClient.newCall(request); + } + + /* + * Purpose : This function calling the Authentication and making an Auth + * Header + * + */ + + public void callAuthenticationHeader(String method, String path, Object body, List queryParams) { + + try { + merchantConfig.setRequestType(method); + + if (!queryParams.isEmpty()) { + + if (merchantConfig.getAuthenticationType().equalsIgnoreCase(GlobalLabelParameters.HTTP)) { + boolean firstQueryParam = true; + for (Pair pair : queryParams) { + + String key = pair.getName(); + String val = pair.getValue(); + val = val.replaceAll(" ", "%20"); + + if (!firstQueryParam) { + path = path + "&" + key + "=" + val; + } else { + path = path + "?" + key + "=" + val; + firstQueryParam = false; + } + } + merchantConfig.setRequestTarget(path); + + } + } else { + + merchantConfig.setRequestTarget(path); + } + + Authorization authorization = new Authorization(); + Logger logger = Log4j.getInstance(merchantConfig); + authorization.setLogger(logger); + + String requestBody = json.serialize(body); + merchantConfig.setRequestData(requestBody); + authorization.setJWTRequestBody(requestBody); + merchantConfig.setRequestJsonPath(GlobalLabelParameters.POST_OBJECT_METHOD_REQUEST_PATH); + boolean isMerchantDetails = merchantConfig.validateMerchantDetails(logger); + + if (isMerchantDetails) { + String token = authorization.getToken(merchantConfig); + if (merchantConfig.getAuthenticationType().equalsIgnoreCase(GlobalLabelParameters.HTTP)) { + + addDefaultHeader("Date", PropertiesUtil.date); + addDefaultHeader("Host", merchantConfig.getRequestHost()); + addDefaultHeader("v-c-merchant-id", merchantConfig.getMerchantID()); + addDefaultHeader("Signature", token); + addDefaultHeader("User-Agent", "Mozilla/5.0"); + + if (method.equalsIgnoreCase("POST") || method.equalsIgnoreCase("PUT") + || method.equalsIgnoreCase("PATCH")) { + PayloadDigest payloadDigest = new PayloadDigest(merchantConfig); + String digest = payloadDigest.getDigest(); + addDefaultHeader("Digest", digest); + } + + } else if (merchantConfig.getAuthenticationType().equalsIgnoreCase(GlobalLabelParameters.JWT)) { + token = "Bearer " + token; + addDefaultHeader("Authorization", token); + } + } + + } catch (ConfigException e) { + System.out.println(e.getMessage()); + } + + } + + /** + * Build an HTTP request with the given options. + * + * @param path + * The sub-path of the HTTP URL + * @param method + * The request method, one of "GET", "HEAD", "OPTIONS", "POST", + * "PUT", "PATCH" and "DELETE" + * @param queryParams + * The query parameters + * @param body + * The request body object + * @param headerParams + * The header parameters + * @param formParams + * The form parameters + * @param authNames + * The authentications to apply + * @param progressRequestListener + * Progress request listener + * @return The HTTP request + * @throws ApiException + * If fail to serialize the request body object + */ + public Request buildRequest(String path, String method, List queryParams, Object body, + Map headerParams, Map formParams, String[] authNames, + ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException { + updateParamsForAuth(authNames, queryParams, headerParams); + + final String url = buildUrl(path, queryParams); + final Request.Builder reqBuilder = new Request.Builder().url(url); + processHeaderParams(headerParams, reqBuilder); + + String contentType = (String) headerParams.get("Content-Type"); + // ensuring a default content type + if (contentType == null) { + contentType = "application/json"; + } + + RequestBody reqBody; + if (!HttpMethod.permitsRequestBody(method)) { + reqBody = null; + } else if ("application/x-www-form-urlencoded".equals(contentType)) { + reqBody = buildRequestBodyFormEncoding(formParams); + } else if ("multipart/form-data".equals(contentType)) { + reqBody = buildRequestBodyMultipart(formParams); + } else if (body == null) { + if ("DELETE".equals(method)) { + // allow calling DELETE without sending a request body + reqBody = null; + } else { + // use an empty request body (for POST, PUT and PATCH) + reqBody = RequestBody.create(MediaType.parse(contentType), ""); + } + } else { + reqBody = serialize(body, contentType); + } + + Request request = null; + + if (progressRequestListener != null && reqBody != null) { + ProgressRequestBody progressRequestBody = new ProgressRequestBody(reqBody, progressRequestListener); + request = reqBuilder.method(method, progressRequestBody).build(); + } else { + request = reqBuilder.method(method, reqBody).build(); + } + + return request; + } + + /** + * Build full URL by concatenating base path, the given sub path and query + * parameters. + * + * @param path + * The sub path + * @param queryParams + * The query parameters + * @return The full URL + */ + public String buildUrl(String path, List queryParams) { + final StringBuilder url = new StringBuilder(); + url.append(GlobalLabelParameters.URL_PREFIX).append(merchantConfig.getRequestHost()).append(path); + + if (queryParams != null && !queryParams.isEmpty()) { + // support (constant) query string in `path`, e.g. "/posts?draft=1" + String prefix = path.contains("?") ? "&" : "?"; + for (Pair param : queryParams) { + if (param.getValue() != null) { + if (prefix != null) { + url.append(prefix); + prefix = null; + } else { + url.append("&"); + } + String value = parameterToString(param.getValue()); + url.append(escapeString(param.getName())).append("=").append(escapeString(value)); + } + } + } + + return url.toString(); + } + + /** + * Set header parameters to the request builder, including default headers. + * + * @param headerParams + * Header parameters in the ofrm of Map + * @param reqBuilder + * Reqeust.Builder + */ + public void processHeaderParams(Map headerParams, Request.Builder reqBuilder) { + for (Entry param : headerParams.entrySet()) { + reqBuilder.header(param.getKey(), parameterToString(param.getValue())); + } + for (Entry header : defaultHeaderMap.entrySet()) { + if (!headerParams.containsKey(header.getKey())) { + reqBuilder.header(header.getKey(), parameterToString(header.getValue())); + } + } + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames + * The authentications to apply + * @param queryParams + * List of query parameters + * @param headerParams + * Map of header parameters + */ + public void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) + throw new RuntimeException("Authentication undefined: " + authName); + auth.applyToParams(queryParams, headerParams); + } + } + + /** + * Build a form-encoding request body with the given form parameters. + * + * @param formParams + * Form parameters in the form of Map + * @return RequestBody + */ + public RequestBody buildRequestBodyFormEncoding(Map formParams) { + FormEncodingBuilder formBuilder = new FormEncodingBuilder(); + for (Entry param : formParams.entrySet()) { + formBuilder.add(param.getKey(), parameterToString(param.getValue())); + } + return formBuilder.build(); + } + + /** + * Build a multipart (file uploading) request body with the given form + * parameters, which could contain text fields and file fields. + * + * @param formParams + * Form parameters in the form of Map + * @return RequestBody + */ + public RequestBody buildRequestBodyMultipart(Map formParams) { + MultipartBuilder mpBuilder = new MultipartBuilder().type(MultipartBuilder.FORM); + for (Entry param : formParams.entrySet()) { + if (param.getValue() instanceof File) { + File file = (File) param.getValue(); + Headers partHeaders = Headers.of("Content-Disposition", + "form-data; name=\"" + param.getKey() + "\"; filename=\"" + file.getName() + "\""); + MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file)); + mpBuilder.addPart(partHeaders, RequestBody.create(mediaType, file)); + } else { + Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\""); + mpBuilder.addPart(partHeaders, RequestBody.create(null, parameterToString(param.getValue()))); + } + } + return mpBuilder.build(); + } + + /** + * Guess Content-Type header from the given file (defaults to + * "application/octet-stream"). + * + * @param file + * The given file + * @return The guessed Content-Type + */ + public String guessContentTypeFromFile(File file) { + String contentType = URLConnection.guessContentTypeFromName(file.getName()); + if (contentType == null) { + return "application/octet-stream"; + } else { + return contentType; + } + } + + /** + * Initialize datetime format according to the current environment, e.g. + * Java 1.7 and Android. + */ + private void initDatetimeFormat() { + String formatWithTimeZone = null; + if (IS_ANDROID) { + if (ANDROID_SDK_VERSION >= 18) { + // The time zone format "ZZZZZ" is available since Android 4.3 + // (SDK version 18) + formatWithTimeZone = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"; + } + } else if (JAVA_VERSION >= 1.7) { + // The time zone format "XXX" is available since Java 1.7 + formatWithTimeZone = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; + } + if (formatWithTimeZone != null) { + this.datetimeFormat = new SimpleDateFormat(formatWithTimeZone); + // NOTE: Use the system's default time zone (mainly for datetime + // formatting). + } else { + // Use a common format that works across all systems. + this.datetimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + // Always use the UTC time zone as we are using a constant trailing + // "Z" here. + this.datetimeFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + } + + /** + * Apply SSL related settings to httpClient according to the current values + * of verifyingSsl and sslCaCert. + */ + private void applySslSettings() { + try { + TrustManager[] trustManagers = null; + HostnameVerifier hostnameVerifier = null; + if (!verifyingSsl) { + TrustManager trustAll = new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + SSLContext sslContext = SSLContext.getInstance("TLS"); + trustManagers = new TrustManager[] { trustAll }; + hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + } else if (sslCaCert != null) { + char[] password = null; // Any password will work. + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + Collection certificates = certificateFactory.generateCertificates(sslCaCert); + if (certificates.isEmpty()) { + throw new IllegalArgumentException("expected non-empty set of trusted certificates"); + } + KeyStore caKeyStore = newEmptyKeyStore(password); + int index = 0; + for (Certificate certificate : certificates) { + String certificateAlias = "ca" + Integer.toString(index++); + caKeyStore.setCertificateEntry(certificateAlias, certificate); + } + TrustManagerFactory trustManagerFactory = TrustManagerFactory + .getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(caKeyStore); + trustManagers = trustManagerFactory.getTrustManagers(); + } + + if (keyManagers != null || trustManagers != null) { + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagers, trustManagers, new SecureRandom()); + httpClient.setSslSocketFactory(sslContext.getSocketFactory()); + } else { + httpClient.setSslSocketFactory(null); + } + httpClient.setHostnameVerifier(hostnameVerifier); + } catch (GeneralSecurityException e) { + throw new RuntimeException(e); + } + } + + private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException { + try { + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, password); + return keyStore; + } catch (IOException e) { + throw new AssertionError(e); + } + } +} diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/ApiResponse.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/ApiResponse.mustache new file mode 100644 index 000000000..390939369 --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/ApiResponse.mustache @@ -0,0 +1,48 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import java.util.List; +import java.util.Map; + +/** + * API response returned by API call. + * + * @param The type of data that is deserialized from response body + */ +public class ApiResponse { + final private int statusCode; + final private Map> headers; + final private T data; + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + */ + public ApiResponse(int statusCode, Map> headers) { + this(statusCode, headers, null); + } + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + * @param data The object deserialized from response bod + */ + public ApiResponse(int statusCode, Map> headers, T data) { + this.statusCode = statusCode; + this.headers = headers; + this.data = data; + } + + public int getStatusCode() { + return statusCode; + } + + public Map> getHeaders() { + return headers; + } + + public T getData() { + return data; + } +} diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/GzipRequestInterceptor.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/GzipRequestInterceptor.mustache new file mode 100644 index 000000000..23224cf5d --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/GzipRequestInterceptor.mustache @@ -0,0 +1,70 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import com.squareup.okhttp.*; +import okio.Buffer; +import okio.BufferedSink; +import okio.GzipSink; +import okio.Okio; + +import java.io.IOException; + +/** + * Encodes request bodies using gzip. + * + * Taken from https://github.com/square/okhttp/issues/350 + */ +class GzipRequestInterceptor implements Interceptor { + @Override public Response intercept(Chain chain) throws IOException { + Request originalRequest = chain.request(); + if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { + return chain.proceed(originalRequest); + } + + Request compressedRequest = originalRequest.newBuilder() + .header("Content-Encoding", "gzip") + .method(originalRequest.method(), forceContentLength(gzip(originalRequest.body()))) + .build(); + return chain.proceed(compressedRequest); + } + + private RequestBody forceContentLength(final RequestBody requestBody) throws IOException { + final Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + return new RequestBody() { + @Override + public MediaType contentType() { + return requestBody.contentType(); + } + + @Override + public long contentLength() { + return buffer.size(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + sink.write(buffer.snapshot()); + } + }; + } + + private RequestBody gzip(final RequestBody body) { + return new RequestBody() { + @Override public MediaType contentType() { + return body.contentType(); + } + + @Override public long contentLength() { + return -1; // We don't know the compressed length in advance! + } + + @Override public void writeTo(BufferedSink sink) throws IOException { + BufferedSink gzipSink = Okio.buffer(new GzipSink(sink)); + body.writeTo(gzipSink); + gzipSink.close(); + } + }; + } +} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/JSON.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/JSON.mustache new file mode 100644 index 000000000..10a377ebb --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/JSON.mustache @@ -0,0 +1,291 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; +import java.io.StringReader; +import java.lang.reflect.Type; +import java.util.Date; + +{{^java8}} +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; +{{/java8}} +{{#java8}} +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +{{/java8}} + +public class JSON { + private ApiClient apiClient; + private Gson gson; + + /** + * JSON constructor. + * + * @param apiClient An instance of ApiClient + */ + public JSON(ApiClient apiClient) { + this.apiClient = apiClient; + gson = new GsonBuilder() + .registerTypeAdapter(Date.class, new DateAdapter(apiClient)) + {{^java8}} + .registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter()) + {{/java8}} + {{#java8}} + .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter()) + {{/java8}} + .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()) + .create(); + } + + /** + * Get Gson. + * + * @return Gson + */ + public Gson getGson() { + return gson; + } + + /** + * Set Gson. + * + * @param gson Gson + */ + public void setGson(Gson gson) { + this.gson = gson; + } + + /** + * Serialize the given Java object into JSON string. + * + * @param obj Object + * @return String representation of the JSON + */ + public String serialize(Object obj) { + return gson.toJson(obj); + } + + /** + * Deserialize the given JSON string to Java object. + * + * @param Type + * @param body The JSON string + * @param returnType The type to deserialize into + * @return The deserialized Java object + */ + @SuppressWarnings("unchecked") + public T deserialize(String body, Type returnType) { + try { + if (apiClient.isLenientOnJson()) { + JsonReader jsonReader = new JsonReader(new StringReader(body)); + // see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean) + jsonReader.setLenient(true); + return gson.fromJson(jsonReader, returnType); + } else { + return gson.fromJson(body, returnType); + } + } catch (JsonParseException e) { + // Fallback processing when failed to parse JSON form response body: + // return the response body string directly for the String return type; + // parse response body into date or datetime for the Date return type. + if (returnType.equals(String.class)) + return (T) body; + else if (returnType.equals(Date.class)) + return (T) apiClient.parseDateOrDatetime(body); + else throw(e); + } + } +} + +class DateAdapter implements JsonSerializer, JsonDeserializer { + private final ApiClient apiClient; + + /** + * Constructor for DateAdapter + * + * @param apiClient Api client + */ + public DateAdapter(ApiClient apiClient) { + super(); + this.apiClient = apiClient; + } + + /** + * Serialize + * + * @param src Date + * @param typeOfSrc Type + * @param context Json Serialization Context + * @return Json Element + */ + @Override + public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) { + if (src == null) { + return JsonNull.INSTANCE; + } else { + return new JsonPrimitive(apiClient.formatDatetime(src)); + } + } + + /** + * Deserialize + * + * @param json Json element + * @param date Type + * @param context Json Serialization Context + * @return Date + * @throws JsonParseException if fail to parse + */ + @Override + public Date deserialize(JsonElement json, Type date, JsonDeserializationContext context) throws JsonParseException { + String str = json.getAsJsonPrimitive().getAsString(); + try { + return apiClient.parseDateOrDatetime(str); + } catch (RuntimeException e) { + throw new JsonParseException(e); + } + } +} + +{{^java8}} +/** + * Gson TypeAdapter for Joda DateTime type + */ +class DateTimeTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter parseFormatter = ISODateTimeFormat.dateOptionalTimeParser(); + private final DateTimeFormatter printFormatter = ISODateTimeFormat.dateTime(); + + @Override + public void write(JsonWriter out, DateTime date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(printFormatter.print(date)); + } + } + + @Override + public DateTime read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return parseFormatter.parseDateTime(date); + } + } +} + +/** + * Gson TypeAdapter for Joda LocalDate type + */ +class LocalDateTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter formatter = ISODateTimeFormat.date(); + + @Override + public void write(JsonWriter out, LocalDate date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.print(date)); + } + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return formatter.parseLocalDate(date); + } + } +} +{{/java8}} +{{#java8}} +/** + * Gson TypeAdapter for jsr310 OffsetDateTime type + */ +class OffsetDateTimeTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; + + @Override + public void write(JsonWriter out, OffsetDateTime date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.format(date)); + } + } + + @Override + public OffsetDateTime read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + if (date.endsWith("+0000")) { + date = date.substring(0, date.length()-5) + "Z"; + } + + return OffsetDateTime.parse(date, formatter); + } + } +} + +/** + * Gson TypeAdapter for jsr310 LocalDate type + */ +class LocalDateTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE; + + @Override + public void write(JsonWriter out, LocalDate date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.format(date)); + } + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return LocalDate.parse(date, formatter); + } + } +} +{{/java8}} diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/ProgressRequestBody.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/ProgressRequestBody.mustache new file mode 100644 index 000000000..0f15c1f41 --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/ProgressRequestBody.mustache @@ -0,0 +1,66 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.RequestBody; + +import java.io.IOException; + +import okio.Buffer; +import okio.BufferedSink; +import okio.ForwardingSink; +import okio.Okio; +import okio.Sink; + +public class ProgressRequestBody extends RequestBody { + + public interface ProgressRequestListener { + void onRequestProgress(long bytesWritten, long contentLength, boolean done); + } + + private final RequestBody requestBody; + + private final ProgressRequestListener progressListener; + + public ProgressRequestBody(RequestBody requestBody, ProgressRequestListener progressListener) { + this.requestBody = requestBody; + this.progressListener = progressListener; + } + + @Override + public MediaType contentType() { + return requestBody.contentType(); + } + + @Override + public long contentLength() throws IOException { + return requestBody.contentLength(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + BufferedSink bufferedSink = Okio.buffer(sink(sink)); + requestBody.writeTo(bufferedSink); + bufferedSink.flush(); + } + + private Sink sink(Sink sink) { + return new ForwardingSink(sink) { + + long bytesWritten = 0L; + long contentLength = 0L; + + @Override + public void write(Buffer source, long byteCount) throws IOException { + super.write(source, byteCount); + if (contentLength == 0) { + contentLength = contentLength(); + } + + bytesWritten += byteCount; + progressListener.onRequestProgress(bytesWritten, contentLength, bytesWritten == contentLength); + } + }; + } +} diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/ProgressResponseBody.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/ProgressResponseBody.mustache new file mode 100644 index 000000000..3f5313369 --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/ProgressResponseBody.mustache @@ -0,0 +1,65 @@ +{{>licenseInfo}} + +package {{invokerPackage}}; + +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.ResponseBody; + +import java.io.IOException; + +import okio.Buffer; +import okio.BufferedSource; +import okio.ForwardingSource; +import okio.Okio; +import okio.Source; + +public class ProgressResponseBody extends ResponseBody { + + public interface ProgressListener { + void update(long bytesRead, long contentLength, boolean done); + } + + private final ResponseBody responseBody; + private final ProgressListener progressListener; + private BufferedSource bufferedSource; + + public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) { + this.responseBody = responseBody; + this.progressListener = progressListener; + } + + @Override + public MediaType contentType() { + return responseBody.contentType(); + } + + @Override + public long contentLength() throws IOException { + return responseBody.contentLength(); + } + + @Override + public BufferedSource source() throws IOException { + if (bufferedSource == null) { + bufferedSource = Okio.buffer(source(responseBody.source())); + } + return bufferedSource; + } + + private Source source(Source source) { + return new ForwardingSource(source) { + long totalBytesRead = 0L; + + @Override + public long read(Buffer sink, long byteCount) throws IOException { + long bytesRead = super.read(sink, byteCount); + // read() returns the number of bytes read, or -1 if this source is exhausted. + totalBytesRead += bytesRead != -1 ? bytesRead : 0; + progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1); + return bytesRead; + } + }; + } +} + + diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/api.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/api.mustache new file mode 100644 index 000000000..49f9ea0a6 --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/api.mustache @@ -0,0 +1,228 @@ +{{>licenseInfo}} + +package {{package}}; + +import {{invokerPackage}}.ApiCallback; +import {{invokerPackage}}.ApiClient; +import {{invokerPackage}}.ApiException; +import {{invokerPackage}}.ApiResponse; +import {{invokerPackage}}.Configuration; +import {{invokerPackage}}.Pair; +import {{invokerPackage}}.ProgressRequestBody; +import {{invokerPackage}}.ProgressResponseBody; +{{#performBeanValidation}} +import {{invokerPackage}}.BeanValidationException; +{{/performBeanValidation}} + +import com.google.gson.reflect.TypeToken; + +import java.io.IOException; + +{{#useBeanValidation}} +import javax.validation.constraints.*; +{{/useBeanValidation}} +{{#performBeanValidation}} +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import javax.validation.executable.ExecutableValidator; +import java.util.Set; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +{{/performBeanValidation}} + +{{#imports}}import {{import}}; +{{/imports}} + +import java.lang.reflect.Type; +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +{{#operations}} +public class {{classname}} { + private ApiClient {{localVariablePrefix}}apiClient; + + public {{classname}}() { + this(Configuration.getDefaultApiClient()); + } + + public {{classname}}(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + public ApiClient getApiClient() { + return {{localVariablePrefix}}apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + {{#operation}} + /** + * Build call for {{operationId}}{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}} + * @param progressListener Progress listener + * @param progressRequestListener Progress request listener + * @return Call to execute + * @throws ApiException If fail to serialize the request body object + */ + public com.squareup.okhttp.Call {{operationId}}Call({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException { + Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}; + + // create path and map variables + String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}} + .replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; + + {{javaUtilPrefix}}List {{localVariablePrefix}}localVarQueryParams = new {{javaUtilPrefix}}ArrayList();{{#queryParams}} + if ({{paramName}} != null) + {{localVariablePrefix}}localVarQueryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));{{/queryParams}} + + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarHeaderParams = new {{javaUtilPrefix}}HashMap();{{#headerParams}} + if ({{paramName}} != null) + {{localVariablePrefix}}localVarHeaderParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{/headerParams}} + + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarFormParams = new {{javaUtilPrefix}}HashMap();{{#formParams}} + if ({{paramName}} != null) + {{localVariablePrefix}}localVarFormParams.put("{{baseName}}", {{paramName}});{{/formParams}} + + final String[] {{localVariablePrefix}}localVarAccepts = { + {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} + }; + final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts); + if ({{localVariablePrefix}}localVarAccept != null) {{localVariablePrefix}}localVarHeaderParams.put("Accept", {{localVariablePrefix}}localVarAccept); + + final String[] {{localVariablePrefix}}localVarContentTypes = { + {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} + }; + final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes); + {{localVariablePrefix}}localVarHeaderParams.put("Content-Type", {{localVariablePrefix}}localVarContentType); + + if(progressListener != null) { + apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() { + @Override + public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException { + com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .body(new ProgressResponseBody(originalResponse.body(), progressListener)) + .build(); + } + }); + } + + String[] {{localVariablePrefix}}localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; + return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAuthNames, progressRequestListener); + } + + @SuppressWarnings("rawtypes") + private com.squareup.okhttp.Call {{operationId}}ValidateBeforeCall({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException { + {{^performBeanValidation}} + {{#allParams}}{{#required}} + // verify the required parameter '{{paramName}}' is set + if ({{paramName}} == null) { + throw new ApiException("Missing the required parameter '{{paramName}}' when calling {{operationId}}(Async)"); + } + {{/required}}{{/allParams}} + + com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener); + return {{localVariablePrefix}}call; + + {{/performBeanValidation}} + {{#performBeanValidation}} + try { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + ExecutableValidator executableValidator = factory.getValidator().forExecutables(); + + Object[] parameterValues = { {{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} }; + Method method = this.getClass().getMethod("{{operationId}}WithHttpInfo"{{#allParams}}, {{#isListContainer}}java.util.List{{/isListContainer}}{{#isMapContainer}}java.util.Map{{/isMapContainer}}{{^isListContainer}}{{^isMapContainer}}{{{dataType}}}{{/isMapContainer}}{{/isListContainer}}.class{{/allParams}}); + Set> violations = executableValidator.validateParameters(this, method, + parameterValues); + + if (violations.size() == 0) { + com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener); + return {{localVariablePrefix}}call; + + } else { + throw new BeanValidationException((Set) violations); + } + } catch (NoSuchMethodException e) { + e.printStackTrace(); + throw new ApiException(e.getMessage()); + } catch (SecurityException e) { + e.printStackTrace(); + throw new ApiException(e.getMessage()); + } + + {{/performBeanValidation}} + + + + + } + + /** + * {{summary}} + * {{notes}}{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}{{#returnType}} + * @return {{returnType}}{{/returnType}} + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + */ + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException { + {{#returnType}}ApiResponse<{{{returnType}}}> {{localVariablePrefix}}resp = {{/returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}} + return {{localVariablePrefix}}resp.getData();{{/returnType}} + } + + /** + * {{summary}} + * {{notes}}{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}} + * @return ApiResponse<{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}> + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + */ + public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException { + com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}null, null); + {{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType(); + return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}localVarReturnType);{{/returnType}}{{^returnType}}return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}} + } + + /** + * {{summary}} (asynchronously) + * {{notes}}{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}} + * @param callback The callback to be executed when the API call finishes + * @return The request call + * @throws ApiException If fail to process the API call, e.g. serializing the request body object + */ + public com.squareup.okhttp.Call {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ApiCallback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{localVariablePrefix}}callback) throws ApiException { + + ProgressResponseBody.ProgressListener progressListener = null; + ProgressRequestBody.ProgressRequestListener progressRequestListener = null; + + if (callback != null) { + progressListener = new ProgressResponseBody.ProgressListener() { + @Override + public void update(long bytesRead, long contentLength, boolean done) { + callback.onDownloadProgress(bytesRead, contentLength, done); + } + }; + + progressRequestListener = new ProgressRequestBody.ProgressRequestListener() { + @Override + public void onRequestProgress(long bytesWritten, long contentLength, boolean done) { + callback.onUploadProgress(bytesWritten, contentLength, done); + } + }; + } + + com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener); + {{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType(); + {{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}localVarReturnType, {{localVariablePrefix}}callback);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}callback);{{/returnType}} + return {{localVariablePrefix}}call; + } + {{/operation}} +} +{{/operations}} diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/auth/HttpBasicAuth.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/auth/HttpBasicAuth.mustache new file mode 100644 index 000000000..320903b03 --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/auth/HttpBasicAuth.mustache @@ -0,0 +1,43 @@ +{{>licenseInfo}} + +package {{invokerPackage}}.auth; + +import {{invokerPackage}}.Pair; + +import com.squareup.okhttp.Credentials; + +import java.util.Map; +import java.util.List; + +import java.io.UnsupportedEncodingException; + +public class HttpBasicAuth implements Authentication { + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public void applyToParams(List queryParams, Map headerParams) { + if (username == null && password == null) { + return; + } + headerParams.put("Authorization", Credentials.basic( + username == null ? "" : username, + password == null ? "" : password)); + } +} diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/build.gradle.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/build.gradle.mustache new file mode 100644 index 000000000..0d169cf9c --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/build.gradle.mustache @@ -0,0 +1,111 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 25 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + + sourceCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} + targetCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} + + install { + repositories.mavenInstaller { + pom.artifactId = '{{artifactId}}' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +dependencies { + compile 'io.swagger:swagger-annotations:1.5.15' + compile 'com.squareup.okhttp:okhttp:2.7.5' + compile 'com.squareup.okhttp:logging-interceptor:2.7.5' + compile 'com.google.code.gson:gson:2.8.1' + {{^java8}} + compile 'joda-time:joda-time:2.9.9' + {{/java8}} + testCompile 'junit:junit:4.12' +} diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/build.sbt.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/build.sbt.mustache new file mode 100644 index 000000000..c2eef2ede --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/build.sbt.mustache @@ -0,0 +1,22 @@ +lazy val root = (project in file(".")). + settings( + organization := "{{groupId}}", + name := "{{artifactId}}", + version := "{{artifactVersion}}", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + "io.swagger" % "swagger-annotations" % "1.5.15", + "com.squareup.okhttp" % "okhttp" % "2.7.5", + "com.squareup.okhttp" % "logging-interceptor" % "2.7.5", + "com.google.code.gson" % "gson" % "2.8.1", + {{^java8}} + "joda-time" % "joda-time" % "2.9.9" % "compile", + {{/java8}} + "junit" % "junit" % "4.12" % "test", + "com.novocode" % "junit-interface" % "0.10" % "test" + ) + ) diff --git a/generator/cybersource-java-template/libraries/okhttp-gson/pom.mustache b/generator/cybersource-java-template/libraries/okhttp-gson/pom.mustache new file mode 100644 index 000000000..e25c5882a --- /dev/null +++ b/generator/cybersource-java-template/libraries/okhttp-gson/pom.mustache @@ -0,0 +1,250 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + 2.2.0 + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-core-version} + + + com.squareup.okhttp + okhttp + ${okhttp-version} + + + com.squareup.okhttp + logging-interceptor + ${okhttp-version} + + + com.google.code.gson + gson + ${gson-version} + + {{^java8}} + + joda-time + joda-time + ${jodatime-version} + + {{/java8}} + {{#useBeanValidation}} + + + javax.validation + validation-api + 1.1.0.Final + provided + + {{/useBeanValidation}} + {{#performBeanValidation}} + + + org.hibernate + hibernate-validator + 5.4.1.Final + + + javax.el + el-api + 2.2 + + {{/performBeanValidation}} + {{#parcelableModel}} + + + com.google.android + android + 4.1.1.4 + provided + + {{/parcelableModel}} + + + junit + junit + ${junit-version} + test + + + + {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + ${java.version} + ${java.version} + 1.5.15 + 2.7.5 + 2.8.1 + 2.9.9 + 1.0.0 + 4.12 + UTF-8 + + diff --git a/generator/cybersource-java-template/libraries/resteasy/ApiClient.mustache b/generator/cybersource-java-template/libraries/resteasy/ApiClient.mustache new file mode 100644 index 000000000..9ca31c607 --- /dev/null +++ b/generator/cybersource-java-template/libraries/resteasy/ApiClient.mustache @@ -0,0 +1,687 @@ +package {{invokerPackage}}; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.file.Files; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.jboss.logging.Logger; +import org.jboss.resteasy.client.jaxrs.internal.ClientConfiguration; +import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput; +import org.jboss.resteasy.spi.ResteasyProviderFactory; + +import {{invokerPackage}}.auth.Authentication; +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; + +{{>generatedAnnotation}} +public class ApiClient { + private Map defaultHeaderMap = new HashMap(); + private String basePath = "{{{basePath}}}"; + private boolean debugging = false; + + private Client httpClient; + private JSON json; + private String tempFolderPath = null; + + private Map authentications; + + private int statusCode; + private Map> responseHeaders; + + private DateFormat dateFormat; + + public ApiClient() { + json = new JSON(); + httpClient = buildHttpClient(debugging); + + this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + + // Use UTC as the default time zone. + this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + this.json.setDateFormat((DateFormat) dateFormat.clone()); + + // Set default User-Agent. + setUserAgent("{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}Swagger-Codegen/{{{artifactVersion}}}/java{{/httpUserAgent}}"); + + // Setup authentications (key: authentication name, value: authentication). + authentications = new HashMap();{{#authMethods}}{{#isBasic}} + authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}} + authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}} + authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}} + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + /** + * Gets the JSON instance to do JSON serialization and deserialization. + */ + public JSON getJSON() { + return json; + } + + public Client getHttpClient() { + return httpClient; + } + + public ApiClient setHttpClient(Client httpClient) { + this.httpClient = httpClient; + return this; + } + + public String getBasePath() { + return basePath; + } + + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Gets the status code of the previous request + */ + public int getStatusCode() { + return statusCode; + } + + /** + * Gets the response headers of the previous request + */ + public Map> getResponseHeaders() { + return responseHeaders; + } + + /** + * Get authentications (key: authentication name, value: authentication). + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set access token for the first OAuth2 authentication. + */ + public void setAccessToken(String accessToken) { + for (Authentication auth : authentications.values()) { + if (auth instanceof OAuth) { + ((OAuth) auth).setAccessToken(accessToken); + return; + } + } + throw new RuntimeException("No OAuth2 authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + */ + public ApiClient setDebugging(boolean debugging) { + this.debugging = debugging; + // Rebuild HTTP Client according to the new "debugging" value. + this.httpClient = buildHttpClient(debugging); + return this; + } + + /** + * The path of temporary folder used to store downloaded files from endpoints + * with file response. The default value is null, i.e. using + * the system's default tempopary folder. + * + * @see https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String,%20java.io.File) + */ + public String getTempFolderPath() { + return tempFolderPath; + } + + public ApiClient setTempFolderPath(String tempFolderPath) { + this.tempFolderPath = tempFolderPath; + return this; + } + + /** + * Get the date format used to parse/format date parameters. + */ + public DateFormat getDateFormat() { + return dateFormat; + } + + /** + * Set the date format used to parse/format date parameters. + */ + public ApiClient setDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + // also set the date format for model (de)serialization with Date properties + this.json.setDateFormat((DateFormat) dateFormat.clone()); + return this; + } + + /** + * Parse the given string into Date object. + */ + public Date parseDate(String str) { + try { + return dateFormat.parse(str); + } catch (java.text.ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * Format the given Date object into string. + */ + public String formatDate(Date date) { + return dateFormat.format(date); + } + + /** + * Format the given parameter object into string. + */ + public String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date) { + return formatDate((Date) param); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for(Object o : (Collection)param) { + if(b.length() > 0) { + b.append(","); + } + b.append(String.valueOf(o)); + } + return b.toString(); + } else { + return String.valueOf(param); + } + } + + /* + Format to {@code Pair} objects. + */ + public List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList(); + + // preconditions + if (name == null || name.isEmpty() || value == null) return params; + + Collection valueCollection = null; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); + return params; + } + + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format + collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv + + // create the params based on the collection format + if (collectionFormat.equals("multi")) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); + } + + return params; + } + + String delimiter = ","; + + if (collectionFormat.equals("csv")) { + delimiter = ","; + } else if (collectionFormat.equals("ssv")) { + delimiter = " "; + } else if (collectionFormat.equals("tsv")) { + delimiter = "\t"; + } else if (collectionFormat.equals("pipes")) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + + return params; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + */ + public boolean isJsonMime(String mime) { + return mime != null && mime.matches("(?i)application\\/json(;.*)?"); + } + + /** + * Select the Accept header's value from the given accepts array: + * if JSON exists in the given array, use it; + * otherwise use all of them (joining into a string) + * + * @param accepts The accepts array to select from + * @return The Accept header to use. If the given array is empty, + * null will be returned (not to set the Accept header explicitly). + */ + public String selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) { + return null; + } + for (String accept : accepts) { + if (isJsonMime(accept)) { + return accept; + } + } + return StringUtil.join(accepts, ","); + } + + /** + * Select the Content-Type header's value from the given array: + * if JSON exists in the given array, use it; + * otherwise use the first one of the array. + * + * @param contentTypes The Content-Type array to select from + * @return The Content-Type header to use. If the given array is empty, + * JSON will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0) { + return "application/json"; + } + for (String contentType : contentTypes) { + if (isJsonMime(contentType)) { + return contentType; + } + } + return contentTypes[0]; + } + + /** + * Escape the given string to be used as URL query value. + */ + public String escapeString(String str) { + try { + return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + /** + * Serialize the given Java object into string entity according the given + * Content-Type (only JSON is supported for now). + */ + public Entity serialize(Object obj, Map formParams, String contentType) throws ApiException { + Entity entity = null; + if (contentType.startsWith("multipart/form-data")) { + MultipartFormDataOutput multipart = new MultipartFormDataOutput(); + //MultiPart multiPart = new MultiPart(); + for (Entry param: formParams.entrySet()) { + if (param.getValue() instanceof File) { + File file = (File) param.getValue(); + try { + multipart.addFormData(param.getValue().toString(),new FileInputStream(file),MediaType.APPLICATION_OCTET_STREAM_TYPE); + } catch (FileNotFoundException e) { + throw new ApiException("Could not serialize multipart/form-data "+e.getMessage()); + } + } else { + multipart.addFormData(param.getValue().toString(),param.getValue().toString(),MediaType.APPLICATION_OCTET_STREAM_TYPE); + } + } + entity = Entity.entity(multipart.getFormData(), MediaType.MULTIPART_FORM_DATA_TYPE); + } else if (contentType.startsWith("application/x-www-form-urlencoded")) { + Form form = new Form(); + for (Entry param: formParams.entrySet()) { + form.param(param.getKey(), parameterToString(param.getValue())); + } + entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE); + } else { + // We let jersey handle the serialization + entity = Entity.entity(obj, contentType); + } + return entity; + } + + /** + * Deserialize response body to Java object according to the Content-Type. + */ + public T deserialize(Response response, GenericType returnType) throws ApiException { + if (response == null || returnType == null) { + return null; + } + + if ("byte[]".equals(returnType.toString())) { + // Handle binary response (byte array). + return (T) response.readEntity(byte[].class); + } else if (returnType.equals(File.class)) { + // Handle file downloading. + @SuppressWarnings("unchecked") + T file = (T) downloadFileFromResponse(response); + return file; + } + + String contentType = null; + List contentTypes = response.getHeaders().get("Content-Type"); + if (contentTypes != null && !contentTypes.isEmpty()) + contentType = String.valueOf(contentTypes.get(0)); + if (contentType == null) + throw new ApiException(500, "missing Content-Type in response"); + + return response.readEntity(returnType); + } + + /** + * Download file from the given response. + * @throws ApiException If fail to read file content from response and write to disk + */ + public File downloadFileFromResponse(Response response) throws ApiException { + try { + File file = prepareDownloadFile(response); +{{^supportJava6}} + Files.copy(response.readEntity(InputStream.class), file.toPath()); +{{/supportJava6}} +{{#supportJava6}} + // Java6 falls back to commons.io for file copying + FileUtils.copyToFile(response.readEntity(InputStream.class), file); +{{/supportJava6}} + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + public File prepareDownloadFile(Response response) throws IOException { + String filename = null; + String contentDisposition = (String) response.getHeaders().getFirst("Content-Disposition"); + if (contentDisposition != null && !"".equals(contentDisposition)) { + // Get filename from the Content-Disposition header. + Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + Matcher matcher = pattern.matcher(contentDisposition); + if (matcher.find()) + filename = matcher.group(1); + } + + String prefix = null; + String suffix = null; + if (filename == null) { + prefix = "download-"; + suffix = ""; + } else { + int pos = filename.lastIndexOf("."); + if (pos == -1) { + prefix = filename + "-"; + } else { + prefix = filename.substring(0, pos) + "-"; + suffix = filename.substring(pos); + } + // File.createTempFile requires the prefix to be at least three characters long + if (prefix.length() < 3) + prefix = "download-"; + } + + if (tempFolderPath == null) + return File.createTempFile(prefix, suffix); + else + return File.createTempFile(prefix, suffix, new File(tempFolderPath)); + } + + /** + * Invoke API by sending HTTP request with the given options. + * + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "POST", "PUT", and "DELETE" + * @param queryParams The query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param accept The request's Accept header + * @param contentType The request's Content-Type header + * @param authNames The authentications to apply + * @param returnType The return type into which to deserialize the response + * @return The response body in type of string + */ + public T invokeAPI(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames, GenericType returnType) throws ApiException { + updateParamsForAuth(authNames, queryParams, headerParams); + + // Not using `.target(this.basePath).path(path)` below, + // to support (constant) query string in `path`, e.g. "/posts?draft=1" + WebTarget target = httpClient.target(this.basePath + path); + + if (queryParams != null) { + for (Pair queryParam : queryParams) { + if (queryParam.getValue() != null) { + target = target.queryParam(queryParam.getName(), queryParam.getValue()); + } + } + } + + Invocation.Builder invocationBuilder = target.request().accept(accept); + + for (String key : headerParams.keySet()) { + String value = headerParams.get(key); + if (value != null) { + invocationBuilder = invocationBuilder.header(key, value); + } + } + + for (String key : defaultHeaderMap.keySet()) { + if (!headerParams.containsKey(key)) { + String value = defaultHeaderMap.get(key); + if (value != null) { + invocationBuilder = invocationBuilder.header(key, value); + } + } + } + + Entity entity = serialize(body, formParams, contentType); + + Response response = null; + + if ("GET".equals(method)) { + response = invocationBuilder.get(); + } else if ("POST".equals(method)) { + response = invocationBuilder.post(entity); + } else if ("PUT".equals(method)) { + response = invocationBuilder.put(entity); + } else if ("DELETE".equals(method)) { + response = invocationBuilder.delete(); + } else if ("PATCH".equals(method)) { + response = invocationBuilder.header("X-HTTP-Method-Override", "PATCH").post(entity); + } else { + throw new ApiException(500, "unknown method type " + method); + } + + statusCode = response.getStatusInfo().getStatusCode(); + responseHeaders = buildResponseHeaders(response); + + if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) { + return null; + } else if (response.getStatusInfo().getFamily().equals(Status.Family.SUCCESSFUL)) { + if (returnType == null) + return null; + else + return deserialize(response, returnType); + } else { + String message = "error"; + String respBody = null; + if (response.hasEntity()) { + try { + respBody = String.valueOf(response.readEntity(String.class)); + message = respBody; + } catch (RuntimeException e) { + // e.printStackTrace(); + } + } + throw new ApiException( + response.getStatus(), + message, + buildResponseHeaders(response), + respBody); + } + } + + /** + * Build the Client used to make HTTP requests. + */ + private Client buildHttpClient(boolean debugging) { + final ClientConfiguration clientConfig = new ClientConfiguration(ResteasyProviderFactory.getInstance()); + clientConfig.register(json); + if(debugging){ + clientConfig.register(Logger.class); + } + return ClientBuilder.newClient(clientConfig); + } + private Map> buildResponseHeaders(Response response) { + Map> responseHeaders = new HashMap>(); + for (Entry> entry: response.getHeaders().entrySet()) { + List values = entry.getValue(); + List headers = new ArrayList(); + for (Object o : values) { + headers.add(String.valueOf(o)); + } + responseHeaders.put(entry.getKey(), headers); + } + return responseHeaders; + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames The authentications to apply + */ + private void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); + auth.applyToParams(queryParams, headerParams); + } + } +} diff --git a/generator/cybersource-java-template/libraries/resteasy/JSON.mustache b/generator/cybersource-java-template/libraries/resteasy/JSON.mustache new file mode 100644 index 000000000..27d2aa65d --- /dev/null +++ b/generator/cybersource-java-template/libraries/resteasy/JSON.mustache @@ -0,0 +1,48 @@ +package {{invokerPackage}}; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.*; +{{#java8}} +import com.fasterxml.jackson.datatype.jsr310.*; +{{/java8}} +{{^java8}} +import com.fasterxml.jackson.datatype.joda.*; +{{/java8}} + +import java.text.DateFormat; + +import javax.ws.rs.ext.ContextResolver; + +{{>generatedAnnotation}} +public class JSON implements ContextResolver { + private ObjectMapper mapper; + + public JSON() { + mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + mapper.setDateFormat(new RFC3339DateFormat()); + {{#java8}} + mapper.registerModule(new JavaTimeModule()); + {{/java8}} + {{^java8}} + mapper.registerModule(new JodaModule()); + {{/java8}} + } + + /** + * Set the date format for JSON (de)serialization with Date properties. + */ + public void setDateFormat(DateFormat dateFormat) { + mapper.setDateFormat(dateFormat); + } + + @Override + public ObjectMapper getContext(Class type) { + return mapper; + } +} diff --git a/generator/cybersource-java-template/libraries/resteasy/api.mustache b/generator/cybersource-java-template/libraries/resteasy/api.mustache new file mode 100644 index 000000000..26cb9d7d9 --- /dev/null +++ b/generator/cybersource-java-template/libraries/resteasy/api.mustache @@ -0,0 +1,99 @@ +package {{package}}; + +import {{invokerPackage}}.ApiException; +import {{invokerPackage}}.ApiClient; +import {{invokerPackage}}.Configuration; +import {{invokerPackage}}.Pair; + +import javax.ws.rs.core.GenericType; + +{{#imports}}import {{import}}; +{{/imports}} + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +{{>generatedAnnotation}} +{{#operations}} +public class {{classname}} { + private ApiClient {{localVariablePrefix}}apiClient; + + public {{classname}}() { + this(Configuration.getDefaultApiClient()); + } + + public {{classname}}(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + public ApiClient getApiClient() { + return {{localVariablePrefix}}apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + {{#operation}} + /** + * {{summary}} + * {{notes}}{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}{{#returnType}} + * @return {{{returnType}}}{{/returnType}} + * @throws ApiException if fails to make API call + */ + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException { + Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}; + {{#allParams}}{{#required}} + // verify the required parameter '{{paramName}}' is set + if ({{paramName}} == null) { + throw new ApiException(400, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + } + {{/required}}{{/allParams}} + // create path and map variables + String {{localVariablePrefix}}localVarPath = "{{{path}}}".replaceAll("\\{format\\}","json"){{#pathParams}} + .replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; + + // query params + {{javaUtilPrefix}}List {{localVariablePrefix}}localVarQueryParams = new {{javaUtilPrefix}}ArrayList(); + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarHeaderParams = new {{javaUtilPrefix}}HashMap(); + {{javaUtilPrefix}}Map {{localVariablePrefix}}localVarFormParams = new {{javaUtilPrefix}}HashMap(); + + {{#queryParams}} + {{localVariablePrefix}}localVarQueryParams.addAll({{localVariablePrefix}}apiClient.parameterToPairs("{{#collectionFormat}}{{{collectionFormat}}}{{/collectionFormat}}", "{{baseName}}", {{paramName}})); + {{/queryParams}} + + {{#headerParams}}if ({{paramName}} != null) + {{localVariablePrefix}}localVarHeaderParams.put("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}})); + {{/headerParams}} + + {{#formParams}}if ({{paramName}} != null) + {{localVariablePrefix}}localVarFormParams.put("{{baseName}}", {{paramName}}); + {{/formParams}} + + final String[] {{localVariablePrefix}}localVarAccepts = { + {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} + }; + final String {{localVariablePrefix}}localVarAccept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}localVarAccepts); + + final String[] {{localVariablePrefix}}localVarContentTypes = { + {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} + }; + final String {{localVariablePrefix}}localVarContentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}localVarContentTypes); + + String[] {{localVariablePrefix}}localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; + + {{#returnType}} + GenericType<{{{returnType}}}> {{localVariablePrefix}}localVarReturnType = new GenericType<{{{returnType}}}>() {}; + return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, {{localVariablePrefix}}localVarReturnType); + {{/returnType}}{{^returnType}} + {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, null); + {{/returnType}} + } + {{/operation}} +} +{{/operations}} diff --git a/generator/cybersource-java-template/libraries/resteasy/build.gradle.mustache b/generator/cybersource-java-template/libraries/resteasy/build.gradle.mustache new file mode 100644 index 000000000..5a8e29157 --- /dev/null +++ b/generator/cybersource-java-template/libraries/resteasy/build.gradle.mustache @@ -0,0 +1,142 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.5.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 23 + buildToolsVersion '23.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 23 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + {{#java8}} + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 + {{/java8}} + + install { + repositories.mavenInstaller { + pom.artifactId = '{{artifactId}}' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +ext { + swagger_annotations_version = "1.5.8" + jackson_version = "2.7.5" + jersey_version = "2.22.2" + {{^java8}} + jodatime_version = "2.9.4" + {{/java8}} + {{#supportJava6}} + commons_io_version=2.5 + commons_lang3_version=3.5 + {{/supportJava6}} + junit_version = "4.12" +} + +dependencies { + compile "io.swagger:swagger-annotations:$swagger_annotations_version" + compile "org.glassfish.jersey.core:jersey-client:$jersey_version" + compile "org.glassfish.jersey.media:jersey-media-multipart:$jersey_version" + compile "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version" + compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + {{#java8}} + compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + {{/java8}} + {{^java8}} + compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + compile "joda-time:joda-time:$jodatime_version" + compile "com.brsanthu:migbase64:2.2" + {{/java8}} + {{#supportJava6}} + compile "commons-io:commons-io:$commons_io_version" + compile "org.apache.commons:commons-lang3:$commons_lang3_version" + {{/supportJava6}} + testCompile "junit:junit:$junit_version" +} diff --git a/generator/cybersource-java-template/libraries/resteasy/build.sbt.mustache b/generator/cybersource-java-template/libraries/resteasy/build.sbt.mustache new file mode 100644 index 000000000..348d29d96 --- /dev/null +++ b/generator/cybersource-java-template/libraries/resteasy/build.sbt.mustache @@ -0,0 +1,34 @@ +lazy val root = (project in file(".")). + settings( + organization := "{{groupId}}", + name := "{{artifactId}}", + version := "{{artifactVersion}}", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + "io.swagger" % "swagger-annotations" % "1.5.8", + "org.glassfish.jersey.core" % "jersey-client" % "2.22.2", + "org.glassfish.jersey.media" % "jersey-media-multipart" % "2.22.2", + "org.glassfish.jersey.media" % "jersey-media-json-jackson" % "2.22.2", + "com.fasterxml.jackson.core" % "jackson-core" % "2.7.5", + "com.fasterxml.jackson.core" % "jackson-annotations" % "2.7.5", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.7.5", + {{#java8}} + "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.7.5", + {{/java8}} + {{^java8}} + "com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.7.5", + "joda-time" % "joda-time" % "2.9.4", + "com.brsanthu" % "migbase64" % "2.2", + {{/java8}} + {{#supportJava6}} + "org.apache.commons" % "commons-lang3" % "3.5", + "commons-io" % "commons-io" % "2.5", + {{/supportJava6}} + "junit" % "junit" % "4.12" % "test", + "com.novocode" % "junit-interface" % "0.10" % "test" + ) + ) diff --git a/generator/cybersource-java-template/libraries/resteasy/pom.mustache b/generator/cybersource-java-template/libraries/resteasy/pom.mustache new file mode 100644 index 000000000..057d3484d --- /dev/null +++ b/generator/cybersource-java-template/libraries/resteasy/pom.mustache @@ -0,0 +1,230 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + + scm:git:git@github.com:swagger-api/swagger-mustache.git + scm:git:git@github.com:swagger-api/swagger-codegen.git + https://github.com/swagger-api/swagger-codegen + + + 2.2.0 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + {{#java8}} + 1.8 + 1.8 + {{/java8}} + {{^java8}} + 1.7 + 1.7 + {{/java8}} + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + + + + io.swagger + swagger-annotations + ${swagger-core-version} + + + + org.jboss.resteasy + resteasy-client + ${resteasy-version} + + + org.jboss.resteasy + resteasy-multipart-provider + ${resteasy-version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + {{#withXml}} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson-version} + + + {{/withXml}} + {{#java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-version} + + {{/java8}} + {{^java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson-version} + + + joda-time + joda-time + ${jodatime-version} + + + + + com.brsanthu + migbase64 + 2.2 + + {{/java8}} + + {{#supportJava6}} + + org.apache.commons + commons-lang3 + ${commons_lang3_version} + + + + commons-io + commons-io + ${commons_io_version} + + {{/supportJava6}} + + org.jboss.resteasy + resteasy-jackson-provider + 3.1.3.Final + + + + junit + junit + ${junit-version} + test + + + + 1.5.15 + 3.1.3.Final + 2.8.9 + {{^java8}} + 2.9.9 + {{/java8}} + {{#supportJava6}} + 2.5 + 3.6 + {{/supportJava6}} + 1.0.0 + 4.12 + + diff --git a/generator/cybersource-java-template/libraries/resttemplate/ApiClient.mustache b/generator/cybersource-java-template/libraries/resttemplate/ApiClient.mustache new file mode 100644 index 000000000..f3c9b9dde --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/ApiClient.mustache @@ -0,0 +1,643 @@ +package {{invokerPackage}}; + +{{#withXml}} +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; +{{/withXml}} +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.InvalidMediaTypeException; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.http.RequestEntity.BodyBuilder; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +{{#withXml}} +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; +{{/withXml}} +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TimeZone; + +import {{invokerPackage}}.auth.Authentication; +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; + +{{>generatedAnnotation}} +@Component("{{invokerPackage}}.ApiClient") +public class ApiClient { + public enum CollectionFormat { + CSV(","), TSV("\t"), SSV(" "), PIPES("|"), MULTI(null); + + private final String separator; + private CollectionFormat(String separator) { + this.separator = separator; + } + + private String collectionToString(Collection collection) { + return StringUtils.collectionToDelimitedString(collection, separator); + } + } + + private boolean debugging = false; + + private HttpHeaders defaultHeaders = new HttpHeaders(); + + private String basePath = "{{basePath}}"; + + private RestTemplate restTemplate; + + private Map authentications; + + private HttpStatus statusCode; + private MultiValueMap responseHeaders; + + private DateFormat dateFormat; + + public ApiClient() { + this.restTemplate = buildRestTemplate(); + init(); + } + + @Autowired + public ApiClient(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + init(); + } + + protected void init() { + // Use RFC3339 format for date and datetime. + // See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14 + this.dateFormat = new RFC3339DateFormat(); + + // Use UTC as the default time zone. + this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + // Set default User-Agent. + setUserAgent("Java-SDK"); + + // Setup authentications (key: authentication name, value: authentication). + authentications = new HashMap();{{#authMethods}}{{#isBasic}} + authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}} + authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}} + authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}} + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + /** + * Get the current base path + * @return String the base path + */ + public String getBasePath() { + return basePath; + } + + /** + * Set the base path, which should include the host + * @param basePath the base path + * @return ApiClient this client + */ + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Gets the status code of the previous request + * @return HttpStatus the status code + */ + public HttpStatus getStatusCode() { + return statusCode; + } + + /** + * Gets the response headers of the previous request + * @return MultiValueMap a map of response headers + */ + public MultiValueMap getResponseHeaders() { + return responseHeaders; + } + + /** + * Get authentications (key: authentication name, value: authentication). + * @return Map the currently configured authentication types + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + * @param username the username + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + * @param password the password + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + * @param apiKey the API key + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + * @param apiKeyPrefix the API key prefix + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set access token for the first OAuth2 authentication. + * @param accessToken the access token + */ + public void setAccessToken(String accessToken) { + for (Authentication auth : authentications.values()) { + if (auth instanceof OAuth) { + ((OAuth) auth).setAccessToken(accessToken); + return; + } + } + throw new RuntimeException("No OAuth2 authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + * @param userAgent the user agent string + * @return ApiClient this client + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param name The header's name + * @param value The header's value + * @return ApiClient this client + */ + public ApiClient addDefaultHeader(String name, String value) { + defaultHeaders.add(name, value); + return this; + } + + public void setDebugging(boolean debugging) { + List currentInterceptors = this.restTemplate.getInterceptors(); + if(debugging) { + if (currentInterceptors == null) { + currentInterceptors = new ArrayList(); + } + ClientHttpRequestInterceptor interceptor = new ApiClientHttpRequestInterceptor(); + currentInterceptors.add(interceptor); + this.restTemplate.setInterceptors(currentInterceptors); + } else { + if (currentInterceptors != null && !currentInterceptors.isEmpty()) { + Iterator iter = currentInterceptors.iterator(); + while (iter.hasNext()) { + ClientHttpRequestInterceptor interceptor = iter.next(); + if (interceptor instanceof ApiClientHttpRequestInterceptor) { + iter.remove(); + } + } + this.restTemplate.setInterceptors(currentInterceptors); + } + } + this.debugging = debugging; + } + + /** + * Check that whether debugging is enabled for this API client. + * @return boolean true if this client is enabled for debugging, false otherwise + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Get the date format used to parse/format date parameters. + * @return DateFormat format + */ + public DateFormat getDateFormat() { + return dateFormat; + } + + /** + * Set the date format used to parse/format date parameters. + * @param dateFormat Date format + * @return API client + */ + public ApiClient setDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + return this; + } + + /** + * Parse the given string into Date object. + */ + public Date parseDate(String str) { + try { + return dateFormat.parse(str); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * Format the given Date object into string. + */ + public String formatDate(Date date) { + return dateFormat.format(date); + } + + /** + * Format the given parameter object into string. + * @param param the object to convert + * @return String the parameter represented as a String + */ + public String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date) { + return formatDate( (Date) param); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for(Object o : (Collection) param) { + if(b.length() > 0) { + b.append(","); + } + b.append(String.valueOf(o)); + } + return b.toString(); + } else { + return String.valueOf(param); + } + } + + /** + * Converts a parameter to a {@link MultiValueMap} for use in REST requests + * @param collectionFormat The format to convert to + * @param name The name of the parameter + * @param value The parameter's value + * @return a Map containing the String value(s) of the input parameter + */ + public MultiValueMap parameterToMultiValueMap(CollectionFormat collectionFormat, String name, Object value) { + final MultiValueMap params = new LinkedMultiValueMap(); + + if (name == null || name.isEmpty() || value == null) { + return params; + } + + if(collectionFormat == null) { + collectionFormat = CollectionFormat.CSV; + } + + Collection valueCollection = null; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } else { + params.add(name, parameterToString(value)); + return params; + } + + if (valueCollection.isEmpty()){ + return params; + } + + if (collectionFormat.equals(CollectionFormat.MULTI)) { + for (Object item : valueCollection) { + params.add(name, parameterToString(item)); + } + return params; + } + + List values = new ArrayList(); + for(Object o : valueCollection) { + values.add(parameterToString(o)); + } + params.add(name, collectionFormat.collectionToString(values)); + + return params; + } + + /** + * Check if the given {@code String} is a JSON MIME. + * @param mediaType the input MediaType + * @return boolean true if the MediaType represents JSON, false otherwise + */ + public boolean isJsonMime(String mediaType) { + try { + return isJsonMime(MediaType.parseMediaType(mediaType)); + } catch (InvalidMediaTypeException e) { + } + return false; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * @param mediaType the input MediaType + * @return boolean true if the MediaType represents JSON, false otherwise + */ + public boolean isJsonMime(MediaType mediaType) { + return mediaType != null && (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType) || mediaType.getSubtype().matches("^.*\\+json[;]?\\s*$")); + } + + /** + * Select the Accept header's value from the given accepts array: + * if JSON exists in the given array, use it; + * otherwise use all of them (joining into a string) + * + * @param accepts The accepts array to select from + * @return List The list of MediaTypes to use for the Accept header + */ + public List selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) { + return null; + } + for (String accept : accepts) { + MediaType mediaType = MediaType.parseMediaType(accept); + if (isJsonMime(mediaType)) { + return Collections.singletonList(mediaType); + } + } + return MediaType.parseMediaTypes(StringUtils.arrayToCommaDelimitedString(accepts)); + } + + /** + * Select the Content-Type header's value from the given array: + * if JSON exists in the given array, use it; + * otherwise use the first one of the array. + * + * @param contentTypes The Content-Type array to select from + * @return MediaType The Content-Type header to use. If the given array is empty, JSON will be used. + */ + public MediaType selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0) { + return MediaType.APPLICATION_JSON; + } + for (String contentType : contentTypes) { + MediaType mediaType = MediaType.parseMediaType(contentType); + if (isJsonMime(mediaType)) { + return mediaType; + } + } + return MediaType.parseMediaType(contentTypes[0]); + } + + /** + * Select the body to use for the request + * @param obj the body object + * @param formParams the form parameters + * @param contentType the content type of the request + * @return Object the selected body + */ + protected Object selectBody(Object obj, MultiValueMap formParams, MediaType contentType) { + boolean isForm = MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType) || MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(contentType); + return isForm ? formParams : obj; + } + + /** + * Invoke API by sending HTTP request with the given options. + * + * @param the return type to use + * @param path The sub-path of the HTTP URL + * @param method The request method + * @param queryParams The query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param accept The request's Accept header + * @param contentType The request's Content-Type header + * @param authNames The authentications to apply + * @param returnType The return type into which to deserialize the response + * @return The response body in chosen type + */ + public T invokeAPI(String path, HttpMethod method, MultiValueMap queryParams, Object body, HttpHeaders headerParams, MultiValueMap formParams, List accept, MediaType contentType, String[] authNames, ParameterizedTypeReference returnType) throws RestClientException { + updateParamsForAuth(authNames, queryParams, headerParams); + + final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(path); + if (queryParams != null) { + builder.queryParams(queryParams); + } + + final BodyBuilder requestBuilder = RequestEntity.method(method, builder.build().toUri()); + if(accept != null) { + requestBuilder.accept(accept.toArray(new MediaType[accept.size()])); + } + if(contentType != null) { + requestBuilder.contentType(contentType); + } + + addHeadersToRequest(headerParams, requestBuilder); + addHeadersToRequest(defaultHeaders, requestBuilder); + + RequestEntity requestEntity = requestBuilder.body(selectBody(body, formParams, contentType)); + + ResponseEntity responseEntity = restTemplate.exchange(requestEntity, returnType); + + statusCode = responseEntity.getStatusCode(); + responseHeaders = responseEntity.getHeaders(); + + if (responseEntity.getStatusCode() == HttpStatus.NO_CONTENT) { + return null; + } else if (responseEntity.getStatusCode().is2xxSuccessful()) { + if (returnType == null) { + return null; + } + return responseEntity.getBody(); + } else { + // The error handler built into the RestTemplate should handle 400 and 500 series errors. + throw new RestClientException("API returned " + statusCode + " and it wasn't handled by the RestTemplate error handler"); + } + } + + /** + * Add headers to the request that is being built + * @param headers The headers to add + * @param requestBuilder The current request + */ + protected void addHeadersToRequest(HttpHeaders headers, BodyBuilder requestBuilder) { + for (Entry> entry : headers.entrySet()) { + List values = entry.getValue(); + for(String value : values) { + if (value != null) { + requestBuilder.header(entry.getKey(), value); + } + } + } + } + + /** + * Build the RestTemplate used to make HTTP requests. + * @return RestTemplate + */ + protected RestTemplate buildRestTemplate() { + {{#withXml}}List> messageConverters = new ArrayList>(); + messageConverters.add(new MappingJackson2HttpMessageConverter()); + XmlMapper xmlMapper = new XmlMapper(); + xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true); + messageConverters.add(new MappingJackson2XmlHttpMessageConverter(xmlMapper)); + + RestTemplate restTemplate = new RestTemplate(messageConverters); + {{/withXml}}{{^withXml}}RestTemplate restTemplate = new RestTemplate();{{/withXml}} + // This allows us to read the response more than once - Necessary for debugging. + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(restTemplate.getRequestFactory())); + return restTemplate; + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames The authentications to apply + * @param queryParams The query parameters + * @param headerParams The header parameters + */ + private void updateParamsForAuth(String[] authNames, MultiValueMap queryParams, HttpHeaders headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) { + throw new RestClientException("Authentication undefined: " + authName); + } + auth.applyToParams(queryParams, headerParams); + } + } + + private class ApiClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { + private final Log log = LogFactory.getLog(ApiClientHttpRequestInterceptor.class); + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { + logRequest(request, body); + ClientHttpResponse response = execution.execute(request, body); + logResponse(response); + return response; + } + + private void logRequest(HttpRequest request, byte[] body) throws UnsupportedEncodingException { + log.info("URI: " + request.getURI()); + log.info("HTTP Method: " + request.getMethod()); + log.info("HTTP Headers: " + headersToString(request.getHeaders())); + log.info("Request Body: " + new String(body, StandardCharsets.UTF_8)); + } + + private void logResponse(ClientHttpResponse response) throws IOException { + log.info("HTTP Status Code: " + response.getRawStatusCode()); + log.info("Status Text: " + response.getStatusText()); + log.info("HTTP Headers: " + headersToString(response.getHeaders())); + log.info("Response Body: " + bodyToString(response.getBody())); + } + + private String headersToString(HttpHeaders headers) { + StringBuilder builder = new StringBuilder(); + for(Entry> entry : headers.entrySet()) { + builder.append(entry.getKey()).append("=["); + for(String value : entry.getValue()) { + builder.append(value).append(","); + } + builder.setLength(builder.length() - 1); // Get rid of trailing comma + builder.append("],"); + } + builder.setLength(builder.length() - 1); // Get rid of trailing comma + return builder.toString(); + } + + private String bodyToString(InputStream body) throws IOException { + StringBuilder builder = new StringBuilder(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(body, StandardCharsets.UTF_8)); + String line = bufferedReader.readLine(); + while (line != null) { + builder.append(line).append(System.lineSeparator()); + line = bufferedReader.readLine(); + } + bufferedReader.close(); + return builder.toString(); + } + } +} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/resttemplate/api.mustache b/generator/cybersource-java-template/libraries/resttemplate/api.mustache new file mode 100644 index 000000000..0bcd442ed --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/api.mustache @@ -0,0 +1,103 @@ +package {{package}}; + +import {{invokerPackage}}.ApiClient; + +{{#imports}}import {{import}}; +{{/imports}} + +{{^fullJavaUtil}}import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map;{{/fullJavaUtil}} + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +{{>generatedAnnotation}} +@Component("{{package}}.{{classname}}") +{{#operations}} +public class {{classname}} { + private ApiClient {{localVariablePrefix}}apiClient; + + public {{classname}}() { + this(new ApiClient()); + } + + @Autowired + public {{classname}}(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + public ApiClient getApiClient() { + return {{localVariablePrefix}}apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.{{localVariablePrefix}}apiClient = apiClient; + } + + {{#operation}} + /** + * {{summary}} + * {{notes}} +{{#responses}} *

{{code}}{{#message}} - {{message}}{{/message}} +{{/responses}}{{#allParams}} * @param {{paramName}} {{description}}{{^description}}The {{paramName}} parameter{{/description}} +{{/allParams}}{{#returnType}} * @return {{returnType}} +{{/returnType}} * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws RestClientException { + Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}; + {{#allParams}}{{#required}} + // verify the required parameter '{{paramName}}' is set + if ({{paramName}} == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter '{{paramName}}' when calling {{operationId}}"); + } + {{/required}}{{/allParams}}{{#hasPathParams}} + // create path and map variables + final Map uriVariables = new HashMap();{{#pathParams}} + uriVariables.put("{{baseName}}", {{{paramName}}});{{/pathParams}}{{/hasPathParams}} + String {{localVariablePrefix}}path = UriComponentsBuilder.fromPath("{{{path}}}"){{#hasPathParams}}.buildAndExpand(uriVariables){{/hasPathParams}}{{^hasPathParams}}.build(){{/hasPathParams}}.toUriString(); + + final MultiValueMap {{localVariablePrefix}}queryParams = new LinkedMultiValueMap(); + final HttpHeaders {{localVariablePrefix}}headerParams = new HttpHeaders(); + final MultiValueMap {{localVariablePrefix}}formParams = new LinkedMultiValueMap();{{#hasQueryParams}} + + {{#queryParams}}{{localVariablePrefix}}queryParams.putAll({{localVariablePrefix}}apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{collectionFormat}}}".toUpperCase()){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));{{#hasMore}} + {{/hasMore}}{{/queryParams}}{{/hasQueryParams}}{{#hasHeaderParams}} + + {{#headerParams}}if ({{paramName}} != null) + {{localVariablePrefix}}headerParams.add("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{#hasMore}} + {{/hasMore}}{{/headerParams}}{{/hasHeaderParams}}{{#hasFormParams}} + + {{#formParams}}if ({{paramName}} != null) + {{localVariablePrefix}}formParams.add("{{baseName}}", {{#isFile}}new FileSystemResource({{paramName}}){{/isFile}}{{^isFile}}{{paramName}}{{/isFile}});{{#hasMore}} + {{/hasMore}}{{/formParams}}{{/hasFormParams}} + + final String[] {{localVariablePrefix}}accepts = { {{#hasProduces}} + {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} + {{/hasProduces}}}; + final List {{localVariablePrefix}}accept = {{localVariablePrefix}}apiClient.selectHeaderAccept({{localVariablePrefix}}accepts); + final String[] {{localVariablePrefix}}contentTypes = { {{#hasConsumes}} + {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} + {{/hasConsumes}}}; + final MediaType {{localVariablePrefix}}contentType = {{localVariablePrefix}}apiClient.selectHeaderContentType({{localVariablePrefix}}contentTypes); + + String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; + + {{#returnType}}ParameterizedTypeReference<{{{returnType}}}> {{localVariablePrefix}}returnType = new ParameterizedTypeReference<{{{returnType}}}>() {};{{/returnType}}{{^returnType}}ParameterizedTypeReference {{localVariablePrefix}}returnType = new ParameterizedTypeReference() {};{{/returnType}} + {{#returnType}}return {{/returnType}}{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, HttpMethod.{{httpMethod}}, {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType); + } + {{/operation}} +} +{{/operations}} diff --git a/generator/cybersource-java-template/libraries/resttemplate/api_test.mustache b/generator/cybersource-java-template/libraries/resttemplate/api_test.mustache new file mode 100644 index 000000000..127ac2def --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/api_test.mustache @@ -0,0 +1,44 @@ +{{>licenseInfo}} + +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} +import org.junit.Test; +import org.junit.Ignore; + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +/** + * API tests for {{classname}} + */ +@Ignore +public class {{classname}}Test { + + private final {{classname}} api = new {{classname}}(); + + {{#operations}}{{#operation}} + /** + * {{summary}} + * + * {{notes}} + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void {{operationId}}Test() { + {{#allParams}} + {{{dataType}}} {{paramName}} = null; + {{/allParams}} + {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + + // TODO: test validations + } + {{/operation}}{{/operations}} +} diff --git a/generator/cybersource-java-template/libraries/resttemplate/auth/ApiKeyAuth.mustache b/generator/cybersource-java-template/libraries/resttemplate/auth/ApiKeyAuth.mustache new file mode 100644 index 000000000..8b8c40fde --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/auth/ApiKeyAuth.mustache @@ -0,0 +1,60 @@ +package {{invokerPackage}}.auth; + +import org.springframework.http.HttpHeaders; +import org.springframework.util.MultiValueMap; + +{{>generatedAnnotation}} +public class ApiKeyAuth implements Authentication { + private final String location; + private final String paramName; + + private String apiKey; + private String apiKeyPrefix; + + public ApiKeyAuth(String location, String paramName) { + this.location = location; + this.paramName = paramName; + } + + public String getLocation() { + return location; + } + + public String getParamName() { + return paramName; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getApiKeyPrefix() { + return apiKeyPrefix; + } + + public void setApiKeyPrefix(String apiKeyPrefix) { + this.apiKeyPrefix = apiKeyPrefix; + } + + @Override + public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams) { + if (apiKey == null) { + return; + } + String value; + if (apiKeyPrefix != null) { + value = apiKeyPrefix + " " + apiKey; + } else { + value = apiKey; + } + if (location.equals("query")) { + queryParams.add(paramName, value); + } else if (location.equals("header")) { + headerParams.add(paramName, value); + } + } +} diff --git a/generator/cybersource-java-template/libraries/resttemplate/auth/Authentication.mustache b/generator/cybersource-java-template/libraries/resttemplate/auth/Authentication.mustache new file mode 100644 index 000000000..586de7083 --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/auth/Authentication.mustache @@ -0,0 +1,13 @@ +package {{invokerPackage}}.auth; + +import org.springframework.http.HttpHeaders; +import org.springframework.util.MultiValueMap; + +public interface Authentication { + /** + * Apply authentication settings to header and / or query parameters. + * @param queryParams The query parameters for the request + * @param headerParams The header parameters for the request + */ + public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams); +} diff --git a/generator/cybersource-java-template/libraries/resttemplate/auth/HttpBasicAuth.mustache b/generator/cybersource-java-template/libraries/resttemplate/auth/HttpBasicAuth.mustache new file mode 100644 index 000000000..5f535b369 --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/auth/HttpBasicAuth.mustache @@ -0,0 +1,39 @@ +package {{invokerPackage}}.auth; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; + +import org.springframework.http.HttpHeaders; +import org.springframework.util.Base64Utils; +import org.springframework.util.MultiValueMap; + +{{>generatedAnnotation}} +public class HttpBasicAuth implements Authentication { + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams) { + if (username == null && password == null) { + return; + } + String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); + headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString(str.getBytes(StandardCharsets.UTF_8))); + } +} diff --git a/generator/cybersource-java-template/libraries/resttemplate/auth/OAuth.mustache b/generator/cybersource-java-template/libraries/resttemplate/auth/OAuth.mustache new file mode 100644 index 000000000..fbb2f7f9c --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/auth/OAuth.mustache @@ -0,0 +1,24 @@ +package {{invokerPackage}}.auth; + +import org.springframework.http.HttpHeaders; +import org.springframework.util.MultiValueMap; + +{{>generatedAnnotation}} +public class OAuth implements Authentication { + private String accessToken; + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + @Override + public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams) { + if (accessToken != null) { + headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); + } + } +} diff --git a/generator/cybersource-java-template/libraries/resttemplate/auth/OAuthFlow.mustache b/generator/cybersource-java-template/libraries/resttemplate/auth/OAuthFlow.mustache new file mode 100644 index 000000000..7ab35f6d8 --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/auth/OAuthFlow.mustache @@ -0,0 +1,5 @@ +package {{invokerPackage}}.auth; + +public enum OAuthFlow { + accessCode, implicit, password, application +} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/resttemplate/build.gradle.mustache b/generator/cybersource-java-template/libraries/resttemplate/build.gradle.mustache new file mode 100644 index 000000000..4738272eb --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/build.gradle.mustache @@ -0,0 +1,134 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.5.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 23 + buildToolsVersion '23.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 22 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + + {{#java8}} + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 + {{/java8}} + + install { + repositories.mavenInstaller { + pom.artifactId = '{{artifactId}}' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +ext { + swagger_annotations_version = "1.5.15" + jackson_version = "2.8.9" + spring_web_version = "4.3.9.RELEASE" + jodatime_version = "2.9.9" + junit_version = "4.12" +} + +dependencies { + compile "io.swagger:swagger-annotations:$swagger_annotations_version" + compile "org.springframework:spring-web:$spring_web_version" + compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" + compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jackson_version" + {{#java8}} + compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version" + {{/java8}} + {{^java8}} + compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version" + compile "joda-time:joda-time:$jodatime_version" + {{/java8}} + {{#withXml}} + compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jackson_version" + {{/withXml}} + testCompile "junit:junit:$junit_version" +} diff --git a/generator/cybersource-java-template/libraries/resttemplate/pom.mustache b/generator/cybersource-java-template/libraries/resttemplate/pom.mustache new file mode 100644 index 000000000..a18dc1677 --- /dev/null +++ b/generator/cybersource-java-template/libraries/resttemplate/pom.mustache @@ -0,0 +1,270 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + 2.2.0 + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + {{#java8}} + 1.8 + 1.8 + {{/java8}} + {{^java8}} + 1.7 + 1.7 + {{/java8}} + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-annotations-version} + + + + + org.springframework + spring-web + ${spring-web-version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + ${jackson-version} + + {{#withXml}} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson-version} + + + {{/withXml}} + {{#java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-version} + + {{/java8}} + {{^java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson-version} + + + joda-time + joda-time + ${jodatime-version} + + {{/java8}} + + + + junit + junit + ${junit-version} + test + + + + UTF-8 + 1.5.15 + 4.3.9.RELEASE + 2.8.9 + {{^java8}} + 2.9.9 + {{/java8}} + 1.0.0 + 4.12 + + diff --git a/generator/cybersource-java-template/libraries/retrofit/ApiClient.mustache b/generator/cybersource-java-template/libraries/retrofit/ApiClient.mustache new file mode 100644 index 000000000..7c45e926b --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/ApiClient.mustache @@ -0,0 +1,418 @@ +package {{invokerPackage}}; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Type; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import retrofit.RestAdapter; +import retrofit.client.OkClient; +import retrofit.converter.ConversionException; +import retrofit.converter.Converter; +import retrofit.converter.GsonConverter; +import retrofit.mime.TypedByteArray; +import retrofit.mime.TypedInput; +import retrofit.mime.TypedOutput; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.squareup.okhttp.Interceptor; +import com.squareup.okhttp.OkHttpClient; + +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; +import {{invokerPackage}}.auth.OAuth.AccessTokenListener; +import {{invokerPackage}}.auth.OAuthFlow; + + +public class ApiClient { + + private Map apiAuthorizations; + private OkHttpClient okClient; + private RestAdapter.Builder adapterBuilder; + + public ApiClient() { + apiAuthorizations = new LinkedHashMap(); + createDefaultAdapter(); + } + + public ApiClient(String[] authNames) { + this(); + for(String authName : authNames) { + {{#hasAuthMethods}} + Interceptor auth; + {{#authMethods}}if ("{{name}}".equals(authName)) { + {{#isBasic}} + auth = new HttpBasicAuth(); + {{/isBasic}} + {{#isApiKey}} + auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}} + {{#isOAuth}} + auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}"); + {{/isOAuth}} + } else {{/authMethods}}{ + throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names"); + } + addAuthorization(authName, auth); + {{/hasAuthMethods}} + {{^hasAuthMethods}} + throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names"); + {{/hasAuthMethods}} + } + } + + /** + * Basic constructor for single auth name + * @param authName Authentication name + */ + public ApiClient(String authName) { + this(new String[]{authName}); + } + + /** + * Helper constructor for single api key + * @param authName Authentication name + * @param apiKey API key + */ + public ApiClient(String authName, String apiKey) { + this(authName); + this.setApiKey(apiKey); + } + + /** + * Helper constructor for single basic auth or password oauth2 + * @param authName Authentication name + * @param username Username + * @param password Password + */ + public ApiClient(String authName, String username, String password) { + this(authName); + this.setCredentials(username, password); + } + + /** + * Helper constructor for single password oauth2 + * @param authName Authentication name + * @param clientId Client ID + * @param secret Client secret + * @param username Username + * @param password Password + */ + public ApiClient(String authName, String clientId, String secret, String username, String password) { + this(authName); + this.getTokenEndPoint() + .setClientId(clientId) + .setClientSecret(secret) + .setUsername(username) + .setPassword(password); + } + + public void createDefaultAdapter() { + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") + .registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter()) + .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()) + .create(); + + okClient = new OkHttpClient(); + + adapterBuilder = new RestAdapter + .Builder() + .setEndpoint("{{{basePath}}}") + .setClient(new OkClient(okClient)) + .setConverter(new GsonConverterWrapper(gson)); + } + + public S createService(Class serviceClass) { + return adapterBuilder.build().create(serviceClass); + + } + + /** + * Helper method to configure the first api key found + * @param apiKey API key + */ + private void setApiKey(String apiKey) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof ApiKeyAuth) { + ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization; + keyAuth.setApiKey(apiKey); + return; + } + } + } + + /** + * Helper method to configure the username/password for basic auth or password oauth + * @param username Username + * @param password Password + */ + private void setCredentials(String username, String password) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof HttpBasicAuth) { + HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization; + basicAuth.setCredentials(username, password); + return; + } + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.getTokenRequestBuilder().setUsername(username).setPassword(password); + return; + } + } + } + + /** + * Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one) + * @return Token request builder + */ + public TokenRequestBuilder getTokenEndPoint() { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + return oauth.getTokenRequestBuilder(); + } + } + return null; + } + + /** + * Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one) + * @return Authentication request builder + */ + public AuthenticationRequestBuilder getAuthorizationEndPoint() { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + return oauth.getAuthenticationRequestBuilder(); + } + } + return null; + } + + /** + * Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one) + * @param accessToken Access token + */ + public void setAccessToken(String accessToken) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.setAccessToken(accessToken); + return; + } + } + } + + /** + * Helper method to configure the oauth accessCode/implicit flow parameters + * @param clientId Client ID + * @param clientSecret Client secret + * @param redirectURI Redirect URI + */ + public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.getTokenRequestBuilder() + .setClientId(clientId) + .setClientSecret(clientSecret) + .setRedirectURI(redirectURI); + oauth.getAuthenticationRequestBuilder() + .setClientId(clientId) + .setRedirectURI(redirectURI); + return; + } + } + } + + /** + * Configures a listener which is notified when a new access token is received. + * @param accessTokenListener Access token listener + */ + public void registerAccessTokenListener(AccessTokenListener accessTokenListener) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.registerAccessTokenListener(accessTokenListener); + return; + } + } + } + + /** + * Adds an authorization to be used by the client + * @param authName Authentication name + * @param authorization Authorization + */ + public void addAuthorization(String authName, Interceptor authorization) { + if (apiAuthorizations.containsKey(authName)) { + throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations"); + } + apiAuthorizations.put(authName, authorization); + okClient.interceptors().add(authorization); + } + + public Map getApiAuthorizations() { + return apiAuthorizations; + } + + public void setApiAuthorizations(Map apiAuthorizations) { + this.apiAuthorizations = apiAuthorizations; + } + + public RestAdapter.Builder getAdapterBuilder() { + return adapterBuilder; + } + + public void setAdapterBuilder(RestAdapter.Builder adapterBuilder) { + this.adapterBuilder = adapterBuilder; + } + + public OkHttpClient getOkClient() { + return okClient; + } + + public void addAuthsToOkClient(OkHttpClient okClient) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + okClient.interceptors().add(apiAuthorization); + } + } + + /** + * Clones the okClient given in parameter, adds the auth interceptors and uses it to configure the RestAdapter + * @param okClient OkHttp client + */ + public void configureFromOkclient(OkHttpClient okClient) { + OkHttpClient clone = okClient.clone(); + addAuthsToOkClient(clone); + adapterBuilder.setClient(new OkClient(clone)); + } +} + +/** + * This wrapper is to take care of this case: + * when the deserialization fails due to JsonParseException and the + * expected type is String, then just return the body string. + */ +class GsonConverterWrapper implements Converter { + private GsonConverter converter; + + public GsonConverterWrapper(Gson gson) { + converter = new GsonConverter(gson); + } + + @Override public Object fromBody(TypedInput body, Type type) throws ConversionException { + byte[] bodyBytes = readInBytes(body); + TypedByteArray newBody = new TypedByteArray(body.mimeType(), bodyBytes); + try { + return converter.fromBody(newBody, type); + } catch (ConversionException e) { + if (e.getCause() instanceof JsonParseException && type.equals(String.class)) { + return new String(bodyBytes); + } else { + throw e; + } + } + } + + @Override public TypedOutput toBody(Object object) { + return converter.toBody(object); + } + + private byte[] readInBytes(TypedInput body) throws ConversionException { + InputStream in = null; + try { + in = body.in(); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] buffer = new byte[0xFFFF]; + for (int len; (len = in.read(buffer)) != -1;) + os.write(buffer, 0, len); + os.flush(); + return os.toByteArray(); + } catch (IOException e) { + throw new ConversionException(e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ignored) { + } + } + } + + } +} + +/** + * Gson TypeAdapter for Joda DateTime type + */ +class DateTimeTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter parseFormatter = ISODateTimeFormat.dateOptionalTimeParser(); + private final DateTimeFormatter printFormatter = ISODateTimeFormat.dateTime(); + + @Override + public void write(JsonWriter out, DateTime date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(printFormatter.print(date)); + } + } + + @Override + public DateTime read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return parseFormatter.parseDateTime(date); + } + } +} + +/** + * Gson TypeAdapter for Joda DateTime type + */ +class LocalDateTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter formatter = ISODateTimeFormat.date(); + + @Override + public void write(JsonWriter out, LocalDate date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.print(date)); + } + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return formatter.parseLocalDate(date); + } + } +} diff --git a/generator/cybersource-java-template/libraries/retrofit/CollectionFormats.mustache b/generator/cybersource-java-template/libraries/retrofit/CollectionFormats.mustache new file mode 100644 index 000000000..a549ea59d --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/CollectionFormats.mustache @@ -0,0 +1,95 @@ +package {{invokerPackage}}; + +import java.util.Arrays; +import java.util.List; + +public class CollectionFormats { + + public static class CSVParams { + + protected List params; + + public CSVParams() { + } + + public CSVParams(List params) { + this.params = params; + } + + public CSVParams(String... params) { + this.params = Arrays.asList(params); + } + + public List getParams() { + return params; + } + + public void setParams(List params) { + this.params = params; + } + + @Override + public String toString() { + return StringUtil.join(params.toArray(new String[0]), ","); + } + + } + + public static class SSVParams extends CSVParams { + + public SSVParams() { + } + + public SSVParams(List params) { + super(params); + } + + public SSVParams(String... params) { + super(params); + } + + @Override + public String toString() { + return StringUtil.join(params.toArray(new String[0]), " "); + } + } + + public static class TSVParams extends CSVParams { + + public TSVParams() { + } + + public TSVParams(List params) { + super(params); + } + + public TSVParams(String... params) { + super(params); + } + + @Override + public String toString() { + return StringUtil.join( params.toArray(new String[0]), "\t"); + } + } + + public static class PIPESParams extends CSVParams { + + public PIPESParams() { + } + + public PIPESParams(List params) { + super(params); + } + + public PIPESParams(String... params) { + super(params); + } + + @Override + public String toString() { + return StringUtil.join(params.toArray(new String[0]), "|"); + } + } + +} diff --git a/generator/cybersource-java-template/libraries/retrofit/README.mustache b/generator/cybersource-java-template/libraries/retrofit/README.mustache new file mode 100644 index 000000000..56560172e --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/README.mustache @@ -0,0 +1,43 @@ +# {{artifactId}} + +## Requirements + +Building the API client library requires [Maven](https://maven.apache.org/) to be installed. + +## Installation & Usage + +To install the API client library to your local Maven repository, simply execute: + +```shell +mvn install +``` + +To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: + +```shell +mvn deploy +``` + +Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information. + +After the client library is installed/deployed, you can use it in your Maven project by adding the following to your *pom.xml*: + +```xml + + {{groupId}} + {{artifactId}} + {{artifactVersion}} + compile + + +``` + +## Recommendation + +It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. + +## Author + +{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}} +{{/hasMore}}{{/apis}}{{/apiInfo}} + diff --git a/generator/cybersource-java-template/libraries/retrofit/api.mustache b/generator/cybersource-java-template/libraries/retrofit/api.mustache new file mode 100644 index 000000000..5ff729176 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/api.mustache @@ -0,0 +1,56 @@ +package {{package}}; + +import {{invokerPackage}}.CollectionFormats.*; + +import retrofit.Callback; +import retrofit.http.*; +import retrofit.mime.*; + +{{#imports}}import {{import}}; +{{/imports}} + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +{{#operations}} +public interface {{classname}} { + {{#operation}} + /** + * {{summary}} + * Sync method + * {{notes}} +{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} +{{/allParams}} +{{#returnType}} + * @return {{returnType}} +{{/returnType}} + */ + {{#formParams}}{{#-first}} + {{#isMultipart}}@retrofit.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit.http.FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}} + @{{httpMethod}}("{{{path}}}") + {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}} {{operationId}}({{^allParams}});{{/allParams}} + {{#allParams}}{{>libraries/retrofit/queryParams}}{{>libraries/retrofit/pathParams}}{{>libraries/retrofit/headerParams}}{{>libraries/retrofit/bodyParams}}{{>libraries/retrofit/formParams}}{{#hasMore}}, {{/hasMore}}{{^hasMore}} + );{{/hasMore}}{{/allParams}} + + /** + * {{summary}} + * Async method +{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} +{{/allParams}} + * @param cb callback method + */ + {{#formParams}}{{#-first}} + {{#isMultipart}}@retrofit.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit.http.FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}} + @{{httpMethod}}("{{{path}}}") + void {{operationId}}( + {{#allParams}}{{>libraries/retrofit/queryParams}}{{>libraries/retrofit/pathParams}}{{>libraries/retrofit/headerParams}}{{>libraries/retrofit/bodyParams}}{{>libraries/retrofit/formParams}}, {{/allParams}}Callback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> cb + ); + {{/operation}} +} +{{/operations}} diff --git a/generator/cybersource-java-template/libraries/retrofit/api_test.mustache b/generator/cybersource-java-template/libraries/retrofit/api_test.mustache new file mode 100644 index 000000000..a34cfe0e1 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/api_test.mustache @@ -0,0 +1,44 @@ +package {{package}}; + +import {{invokerPackage}}.ApiClient; +{{#imports}}import {{import}}; +{{/imports}} +import org.junit.Before; +import org.junit.Test; + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +/** + * API tests for {{classname}} + */ +public class {{classname}}Test { + + private {{classname}} api; + + @Before + public void setup() { + api = new ApiClient().createService({{classname}}.class); + } + + {{#operations}}{{#operation}} + /** + * {{summary}} + * + * {{notes}} + */ + @Test + public void {{operationId}}Test() { + {{#allParams}} + {{{dataType}}} {{paramName}} = null; + {{/allParams}} + // {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + + // TODO: test validations + } + {{/operation}}{{/operations}} +} diff --git a/generator/cybersource-java-template/libraries/retrofit/auth/ApiKeyAuth.mustache b/generator/cybersource-java-template/libraries/retrofit/auth/ApiKeyAuth.mustache new file mode 100644 index 000000000..f6a86f22a --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/auth/ApiKeyAuth.mustache @@ -0,0 +1,68 @@ +package {{invokerPackage}}.auth; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import com.squareup.okhttp.Interceptor; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + +public class ApiKeyAuth implements Interceptor { + private final String location; + private final String paramName; + + private String apiKey; + + public ApiKeyAuth(String location, String paramName) { + this.location = location; + this.paramName = paramName; + } + + public String getLocation() { + return location; + } + + public String getParamName() { + return paramName; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + @Override + public Response intercept(Chain chain) throws IOException { + String paramValue; + Request request = chain.request(); + + if ("query".equals(location)) { + String newQuery = request.uri().getQuery(); + paramValue = paramName + "=" + apiKey; + if (newQuery == null) { + newQuery = paramValue; + } else { + newQuery += "&" + paramValue; + } + + URI newUri; + try { + newUri = new URI(request.uri().getScheme(), request.uri().getAuthority(), + request.uri().getPath(), newQuery, request.uri().getFragment()); + } catch (URISyntaxException e) { + throw new IOException(e); + } + + request = request.newBuilder().url(newUri.toURL()).build(); + } else if ("header".equals(location)) { + request = request.newBuilder() + .addHeader(paramName, apiKey) + .build(); + } + return chain.proceed(request); + } +} diff --git a/generator/cybersource-java-template/libraries/retrofit/auth/HttpBasicAuth.mustache b/generator/cybersource-java-template/libraries/retrofit/auth/HttpBasicAuth.mustache new file mode 100644 index 000000000..394592f64 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/auth/HttpBasicAuth.mustache @@ -0,0 +1,49 @@ +package {{invokerPackage}}.auth; + +import java.io.IOException; + +import com.squareup.okhttp.Credentials; +import com.squareup.okhttp.Interceptor; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + +public class HttpBasicAuth implements Interceptor { + + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setCredentials(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + + // If the request already have an authorization (eg. Basic auth), do nothing + if (request.header("Authorization") == null) { + String credentials = Credentials.basic(username, password); + request = request.newBuilder() + .addHeader("Authorization", credentials) + .build(); + } + return chain.proceed(request); + } +} diff --git a/generator/cybersource-java-template/libraries/retrofit/auth/OAuth.mustache b/generator/cybersource-java-template/libraries/retrofit/auth/OAuth.mustache new file mode 100644 index 000000000..d0c62ff03 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/auth/OAuth.mustache @@ -0,0 +1,176 @@ +package {{invokerPackage}}.auth; + +import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; +import static java.net.HttpURLConnection.HTTP_FORBIDDEN; + +import java.io.IOException; +import java.util.Map; + +import org.apache.oltu.oauth2.client.OAuthClient; +import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; +import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse; +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; +import org.apache.oltu.oauth2.common.exception.OAuthSystemException; +import org.apache.oltu.oauth2.common.message.types.GrantType; +import org.apache.oltu.oauth2.common.token.BasicOAuthToken; + +import com.squareup.okhttp.Interceptor; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Request.Builder; +import com.squareup.okhttp.Response; + +public class OAuth implements Interceptor { + + public interface AccessTokenListener { + public void notify(BasicOAuthToken token); + } + + private volatile String accessToken; + private OAuthClient oauthClient; + + private TokenRequestBuilder tokenRequestBuilder; + private AuthenticationRequestBuilder authenticationRequestBuilder; + + private AccessTokenListener accessTokenListener; + + public OAuth( OkHttpClient client, TokenRequestBuilder requestBuilder ) { + this.oauthClient = new OAuthClient(new OAuthOkHttpClient(client)); + this.tokenRequestBuilder = requestBuilder; + } + + public OAuth(TokenRequestBuilder requestBuilder ) { + this(new OkHttpClient(), requestBuilder); + } + + public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) { + this(OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes)); + setFlow(flow); + authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl); + } + + public void setFlow(OAuthFlow flow) { + switch(flow) { + case accessCode: + case implicit: + tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE); + break; + case password: + tokenRequestBuilder.setGrantType(GrantType.PASSWORD); + break; + case application: + tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS); + break; + default: + break; + } + } + + @Override + public Response intercept(Chain chain) + throws IOException { + + Request request = chain.request(); + + // If the request already have an authorization (eg. Basic auth), do nothing + if (request.header("Authorization") != null) { + return chain.proceed(request); + } + + // If first time, get the token + OAuthClientRequest oAuthRequest; + if (getAccessToken() == null) { + updateAccessToken(null); + } + + if (getAccessToken() != null) { + // Build the request + Builder rb = request.newBuilder(); + + String requestAccessToken = new String(getAccessToken()); + try { + oAuthRequest = new OAuthBearerClientRequest(request.urlString()) + .setAccessToken(requestAccessToken) + .buildHeaderMessage(); + } catch (OAuthSystemException e) { + throw new IOException(e); + } + + for ( Map.Entry header : oAuthRequest.getHeaders().entrySet() ) { + rb.addHeader(header.getKey(), header.getValue()); + } + rb.url( oAuthRequest.getLocationUri()); + + //Execute the request + Response response = chain.proceed(rb.build()); + + // 401 most likely indicates that access token has expired. + // Time to refresh and resend the request + if ( response != null && (response.code() == HTTP_UNAUTHORIZED | response.code() == HTTP_FORBIDDEN) ) { + if (updateAccessToken(requestAccessToken)) { + return intercept( chain ); + } + } + return response; + } else { + return chain.proceed(chain.request()); + } + } + + /* + * Returns true if the access token has been updated + */ + public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException { + if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) { + try { + OAuthJSONAccessTokenResponse accessTokenResponse = oauthClient.accessToken(this.tokenRequestBuilder.buildBodyMessage()); + if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) { + setAccessToken(accessTokenResponse.getAccessToken()); + if (accessTokenListener != null) { + accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken()); + } + return !getAccessToken().equals(requestAccessToken); + } else { + return false; + } + } catch (OAuthSystemException e) { + throw new IOException(e); + } catch (OAuthProblemException e) { + throw new IOException(e); + } + } + return true; + } + + public void registerAccessTokenListener(AccessTokenListener accessTokenListener) { + this.accessTokenListener = accessTokenListener; + } + + public synchronized String getAccessToken() { + return accessToken; + } + + public synchronized void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public TokenRequestBuilder getTokenRequestBuilder() { + return tokenRequestBuilder; + } + + public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) { + this.tokenRequestBuilder = tokenRequestBuilder; + } + + public AuthenticationRequestBuilder getAuthenticationRequestBuilder() { + return authenticationRequestBuilder; + } + + public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) { + this.authenticationRequestBuilder = authenticationRequestBuilder; + } + +} diff --git a/generator/cybersource-java-template/libraries/retrofit/auth/OAuthOkHttpClient.mustache b/generator/cybersource-java-template/libraries/retrofit/auth/OAuthOkHttpClient.mustache new file mode 100644 index 000000000..ea195f7df --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/auth/OAuthOkHttpClient.mustache @@ -0,0 +1,69 @@ +package {{invokerPackage}}.auth; + +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.oltu.oauth2.client.HttpClient; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest; +import org.apache.oltu.oauth2.client.response.OAuthClientResponse; +import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory; +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; +import org.apache.oltu.oauth2.common.exception.OAuthSystemException; + +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.RequestBody; +import com.squareup.okhttp.Response; + + +public class OAuthOkHttpClient implements HttpClient { + + private OkHttpClient client; + + public OAuthOkHttpClient() { + this.client = new OkHttpClient(); + } + + public OAuthOkHttpClient(OkHttpClient client) { + this.client = client; + } + + public T execute(OAuthClientRequest request, Map headers, + String requestMethod, Class responseClass) + throws OAuthSystemException, OAuthProblemException { + + MediaType mediaType = MediaType.parse("application/json"); + Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri()); + + if(headers != null) { + for (Entry entry : headers.entrySet()) { + if (entry.getKey().equalsIgnoreCase("Content-Type")) { + mediaType = MediaType.parse(entry.getValue()); + } else { + requestBuilder.addHeader(entry.getKey(), entry.getValue()); + } + } + } + + RequestBody body = request.getBody() != null ? RequestBody.create(mediaType, request.getBody()) : null; + requestBuilder.method(requestMethod, body); + + try { + Response response = client.newCall(requestBuilder.build()).execute(); + return OAuthClientResponseFactory.createCustomResponse( + response.body().string(), + response.body().contentType().toString(), + response.code(), + responseClass); + } catch (IOException e) { + throw new OAuthSystemException(e); + } + } + + public void shutdown() { + // Nothing to do here + } + +} diff --git a/generator/cybersource-java-template/libraries/retrofit/bodyParams.mustache b/generator/cybersource-java-template/libraries/retrofit/bodyParams.mustache new file mode 100644 index 000000000..81de324b6 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/bodyParams.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}@retrofit.http.Body {{{dataType}}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit/build.gradle.mustache b/generator/cybersource-java-template/libraries/retrofit/build.gradle.mustache new file mode 100644 index 000000000..60dec7e12 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/build.gradle.mustache @@ -0,0 +1,118 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 25 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 + + install { + repositories.mavenInstaller { + pom.artifactId = '{{artifactId}}' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +ext { + okhttp_version = "2.7.5" + oltu_version = "1.0.1" + retrofit_version = "1.9.0" + swagger_annotations_version = "1.5.8" + junit_version = "4.12" + jodatime_version = "2.9.3" +} + +dependencies { + compile "com.squareup.okhttp:okhttp:$okhttp_version" + compile "com.squareup.retrofit:retrofit:$retrofit_version" + compile "io.swagger:swagger-annotations:$swagger_annotations_version" + compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version" + compile "joda-time:joda-time:$jodatime_version" + testCompile "junit:junit:$junit_version" +} diff --git a/generator/cybersource-java-template/libraries/retrofit/build.sbt.mustache b/generator/cybersource-java-template/libraries/retrofit/build.sbt.mustache new file mode 100644 index 000000000..56f6cee13 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/build.sbt.mustache @@ -0,0 +1,20 @@ +lazy val root = (project in file(".")). + settings( + organization := "{{groupId}}", + name := "{{artifactId}}", + version := "{{artifactVersion}}", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + "com.squareup.okhttp" % "okhttp" % "2.7.5" % "compile", + "com.squareup.retrofit" % "retrofit" % "1.9.0" % "compile", + "io.swagger" % "swagger-annotations" % "1.5.8" % "compile", + "org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile", + "joda-time" % "joda-time" % "2.9.3" % "compile", + "junit" % "junit" % "4.12" % "test", + "com.novocode" % "junit-interface" % "0.10" % "test" + ) + ) diff --git a/generator/cybersource-java-template/libraries/retrofit/formParams.mustache b/generator/cybersource-java-template/libraries/retrofit/formParams.mustache new file mode 100644 index 000000000..f1f9027ae --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/formParams.mustache @@ -0,0 +1 @@ +{{#isFormParam}}{{#notFile}}{{#isMultipart}}@retrofit.http.Part{{/isMultipart}}{{^isMultipart}}@retrofit.http.Field{{/isMultipart}}("{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@retrofit.http.Part{{/isMultipart}}{{^isMultipart}}@retrofit.http.Field{{/isMultipart}}("{{baseName}}") TypedFile {{paramName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit/headerParams.mustache b/generator/cybersource-java-template/libraries/retrofit/headerParams.mustache new file mode 100644 index 000000000..5d6da4a94 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/headerParams.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}@retrofit.http.Header("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit/pathParams.mustache b/generator/cybersource-java-template/libraries/retrofit/pathParams.mustache new file mode 100644 index 000000000..7b8be8442 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/pathParams.mustache @@ -0,0 +1 @@ +{{#isPathParam}}@retrofit.http.Path("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit/pom.mustache b/generator/cybersource-java-template/libraries/retrofit/pom.mustache new file mode 100644 index 000000000..672d4b754 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/pom.mustache @@ -0,0 +1,233 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + 2.2.0 + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-core-version} + + + com.squareup.retrofit + retrofit + ${retrofit-version} + + + org.apache.oltu.oauth2 + org.apache.oltu.oauth2.client + ${oltu-version} + + + com.squareup.okhttp + okhttp + ${okhttp-version} + + + joda-time + joda-time + ${jodatime-version} + + + {{#parcelableModel}} + + + com.google.android + android + 4.1.1.4 + provided + + {{/parcelableModel}} + + + + junit + junit + ${junit-version} + test + + + + 1.5.15 + 1.9.0 + 2.7.5 + 2.9.9 + 1.0.1 + 1.0.0 + 4.12 + + diff --git a/generator/cybersource-java-template/libraries/retrofit/queryParams.mustache b/generator/cybersource-java-template/libraries/retrofit/queryParams.mustache new file mode 100644 index 000000000..2a580ab34 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit/queryParams.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}@retrofit.http.Query("{{baseName}}") {{#collectionFormat}}{{#isCollectionFormatMulti}}{{{dataType}}}{{/isCollectionFormatMulti}}{{^isCollectionFormatMulti}}{{{collectionFormat.toUpperCase}}}Params{{/isCollectionFormatMulti}}{{/collectionFormat}}{{^collectionFormat}}{{{dataType}}}{{/collectionFormat}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit2/ApiClient.mustache b/generator/cybersource-java-template/libraries/retrofit2/ApiClient.mustache new file mode 100644 index 000000000..a0daf87c9 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/ApiClient.mustache @@ -0,0 +1,511 @@ +package {{invokerPackage}}; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; +{{^java8}} +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; +{{/java8}} +{{#java8}} +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +{{/java8}} +import retrofit2.Converter; +import retrofit2.Retrofit; +{{#useRxJava}} +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +{{/useRxJava}} +{{#useRxJava2}} +import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +{{/useRxJava2}} +import retrofit2.converter.gson.GsonConverterFactory; +import retrofit2.converter.scalars.ScalarsConverterFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; + +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; +import {{invokerPackage}}.auth.OAuth.AccessTokenListener; +import {{invokerPackage}}.auth.OAuthFlow; + +public class ApiClient { + + private Map apiAuthorizations; + private OkHttpClient.Builder okBuilder; + private Retrofit.Builder adapterBuilder; + + public ApiClient() { + apiAuthorizations = new LinkedHashMap(); + createDefaultAdapter(); + } + + public ApiClient(String[] authNames) { + this(); + for(String authName : authNames) { + {{#hasAuthMethods}} + Interceptor auth; + {{#authMethods}}if ("{{name}}".equals(authName)) { + {{#isBasic}} + auth = new HttpBasicAuth(); + {{/isBasic}} + {{#isApiKey}} + auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"); + {{/isApiKey}} + {{#isOAuth}} + auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}"); + {{/isOAuth}} + } else {{/authMethods}}{ + throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names"); + } + addAuthorization(authName, auth); + {{/hasAuthMethods}} + {{^hasAuthMethods}} + throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names"); + {{/hasAuthMethods}} + } + } + + /** + * Basic constructor for single auth name + * @param authName Authentication name + */ + public ApiClient(String authName) { + this(new String[]{authName}); + } + + /** + * Helper constructor for single api key + * @param authName Authentication name + * @param apiKey API key + */ + public ApiClient(String authName, String apiKey) { + this(authName); + this.setApiKey(apiKey); + } + + /** + * Helper constructor for single basic auth or password oauth2 + * @param authName Authentication name + * @param username Username + * @param password Password + */ + public ApiClient(String authName, String username, String password) { + this(authName); + this.setCredentials(username, password); + } + + /** + * Helper constructor for single password oauth2 + * @param authName Authentication name + * @param clientId Client ID + * @param secret Client Secret + * @param username Username + * @param password Password + */ + public ApiClient(String authName, String clientId, String secret, String username, String password) { + this(authName); + this.getTokenEndPoint() + .setClientId(clientId) + .setClientSecret(secret) + .setUsername(username) + .setPassword(password); + } + + public void createDefaultAdapter() { + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") + {{^java8}} + .registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter()) + {{/java8}} + {{#java8}} + .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter()) + {{/java8}} + .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()) + .create(); + + okBuilder = new OkHttpClient.Builder(); + + String baseUrl = "{{{basePath}}}"; + if(!baseUrl.endsWith("/")) + baseUrl = baseUrl + "/"; + + adapterBuilder = new Retrofit + .Builder() + .baseUrl(baseUrl) + {{#useRxJava}} + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + {{/useRxJava}} + {{#useRxJava2}} + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + {{/useRxJava2}} + .addConverterFactory(ScalarsConverterFactory.create()) + .addConverterFactory(GsonCustomConverterFactory.create(gson)); + } + + public S createService(Class serviceClass) { + return adapterBuilder + .client(okBuilder.build()) + .build() + .create(serviceClass); + + } + + /** + * Helper method to configure the first api key found + * @param apiKey API key + */ + private void setApiKey(String apiKey) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof ApiKeyAuth) { + ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization; + keyAuth.setApiKey(apiKey); + return; + } + } + } + + /** + * Helper method to configure the username/password for basic auth or password oauth + * @param username Username + * @param password Password + */ + private void setCredentials(String username, String password) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof HttpBasicAuth) { + HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization; + basicAuth.setCredentials(username, password); + return; + } + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.getTokenRequestBuilder().setUsername(username).setPassword(password); + return; + } + } + } + + /** + * Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one) + * @return Token request builder + */ + public TokenRequestBuilder getTokenEndPoint() { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + return oauth.getTokenRequestBuilder(); + } + } + return null; + } + + /** + * Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one) + * @return Authentication request builder + */ + public AuthenticationRequestBuilder getAuthorizationEndPoint() { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + return oauth.getAuthenticationRequestBuilder(); + } + } + return null; + } + + /** + * Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one) + * @param accessToken Access token + */ + public void setAccessToken(String accessToken) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.setAccessToken(accessToken); + return; + } + } + } + + /** + * Helper method to configure the oauth accessCode/implicit flow parameters + * @param clientId Client ID + * @param clientSecret Client secret + * @param redirectURI Redirect URI + */ + public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.getTokenRequestBuilder() + .setClientId(clientId) + .setClientSecret(clientSecret) + .setRedirectURI(redirectURI); + oauth.getAuthenticationRequestBuilder() + .setClientId(clientId) + .setRedirectURI(redirectURI); + return; + } + } + } + + /** + * Configures a listener which is notified when a new access token is received. + * @param accessTokenListener Access token listener + */ + public void registerAccessTokenListener(AccessTokenListener accessTokenListener) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + if (apiAuthorization instanceof OAuth) { + OAuth oauth = (OAuth) apiAuthorization; + oauth.registerAccessTokenListener(accessTokenListener); + return; + } + } + } + + /** + * Adds an authorization to be used by the client + * @param authName Authentication name + * @param authorization Authorization interceptor + */ + public void addAuthorization(String authName, Interceptor authorization) { + if (apiAuthorizations.containsKey(authName)) { + throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations"); + } + apiAuthorizations.put(authName, authorization); + okBuilder.addInterceptor(authorization); + } + + public Map getApiAuthorizations() { + return apiAuthorizations; + } + + public void setApiAuthorizations(Map apiAuthorizations) { + this.apiAuthorizations = apiAuthorizations; + } + + public Retrofit.Builder getAdapterBuilder() { + return adapterBuilder; + } + + public void setAdapterBuilder(Retrofit.Builder adapterBuilder) { + this.adapterBuilder = adapterBuilder; + } + + public OkHttpClient.Builder getOkBuilder() { + return okBuilder; + } + + public void addAuthsToOkBuilder(OkHttpClient.Builder okBuilder) { + for(Interceptor apiAuthorization : apiAuthorizations.values()) { + okBuilder.addInterceptor(apiAuthorization); + } + } + + /** + * Clones the okBuilder given in parameter, adds the auth interceptors and uses it to configure the Retrofit + * @param okClient An instance of OK HTTP client + */ + public void configureFromOkclient(OkHttpClient okClient) { + this.okBuilder = okClient.newBuilder(); + addAuthsToOkBuilder(this.okBuilder); + } +} + +/** + * This wrapper is to take care of this case: + * when the deserialization fails due to JsonParseException and the + * expected type is String, then just return the body string. + */ +class GsonResponseBodyConverterToString implements Converter { + + private final Gson gson; + private final Type type; + + GsonResponseBodyConverterToString(Gson gson, Type type) { + this.gson = gson; + this.type = type; + } + + @Override public T convert(ResponseBody value) throws IOException { + String returned = value.string(); + try { + return gson.fromJson(returned, type); + } + catch (JsonParseException e) { + return (T) returned; + } + } +} + +class GsonCustomConverterFactory extends Converter.Factory { + + private final Gson gson; + private final GsonConverterFactory gsonConverterFactory; + + public static GsonCustomConverterFactory create(Gson gson) { + return new GsonCustomConverterFactory(gson); + } + + private GsonCustomConverterFactory(Gson gson) { + if (gson == null) + throw new NullPointerException("gson == null"); + this.gson = gson; + this.gsonConverterFactory = GsonConverterFactory.create(gson); + } + + @Override + public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { + if (type.equals(String.class)) + return new GsonResponseBodyConverterToString(gson, type); + else + return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit); + } + + @Override + public Converter requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { + return gsonConverterFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit); + } +} + +{{^java8}} +/** + * Gson TypeAdapter for Joda DateTime type + */ +class DateTimeTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter parseFormatter = ISODateTimeFormat.dateOptionalTimeParser(); + private final DateTimeFormatter printFormatter = ISODateTimeFormat.dateTime(); + + @Override + public void write(JsonWriter out, DateTime date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(printFormatter.print(date)); + } + } + + @Override + public DateTime read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return parseFormatter.parseDateTime(date); + } + } +} + +/** + * Gson TypeAdapter for Joda LocalDate type + */ +class LocalDateTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter formatter = ISODateTimeFormat.date(); + + @Override + public void write(JsonWriter out, LocalDate date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.print(date)); + } + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return formatter.parseLocalDate(date); + } + } +} +{{/java8}} +{{#java8}} +/** + * Gson TypeAdapter for jsr310 OffsetDateTime type + */ +class OffsetDateTimeTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; + + @Override + public void write(JsonWriter out, OffsetDateTime date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.format(date)); + } + } + + @Override + public OffsetDateTime read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + if (date.endsWith("+0000")) { + date = date.substring(0, date.length()-5) + "Z"; + } + return OffsetDateTime.parse(date, formatter); + } + } +} + +/** + * Gson TypeAdapter for jsr310 LocalDate type + */ +class LocalDateTypeAdapter extends TypeAdapter { + + private final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE; + + @Override + public void write(JsonWriter out, LocalDate date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.format(date)); + } + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return LocalDate.parse(date, formatter); + } + } +} +{{/java8}} diff --git a/generator/cybersource-java-template/libraries/retrofit2/CollectionFormats.mustache b/generator/cybersource-java-template/libraries/retrofit2/CollectionFormats.mustache new file mode 100644 index 000000000..8c91c335d --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/CollectionFormats.mustache @@ -0,0 +1,95 @@ +package {{invokerPackage}}; + +import java.util.Arrays; +import java.util.List; + +public class CollectionFormats { + + public static class CSVParams { + + protected List params; + + public CSVParams() { + } + + public CSVParams(List params) { + this.params = params; + } + + public CSVParams(String... params) { + this.params = Arrays.asList(params); + } + + public List getParams() { + return params; + } + + public void setParams(List params) { + this.params = params; + } + + @Override + public String toString() { + return StringUtil.join(params.toArray(new String[0]), ","); + } + + } + + public static class SSVParams extends CSVParams { + + public SSVParams() { + } + + public SSVParams(List params) { + super(params); + } + + public SSVParams(String... params) { + super(params); + } + + @Override + public String toString() { + return StringUtil.join(params.toArray(new String[0]), " "); + } + } + + public static class TSVParams extends CSVParams { + + public TSVParams() { + } + + public TSVParams(List params) { + super(params); + } + + public TSVParams(String... params) { + super(params); + } + + @Override + public String toString() { + return StringUtil.join( params.toArray(new String[0]), "\t"); + } + } + + public static class PIPESParams extends CSVParams { + + public PIPESParams() { + } + + public PIPESParams(List params) { + super(params); + } + + public PIPESParams(String... params) { + super(params); + } + + @Override + public String toString() { + return StringUtil.join(params.toArray(new String[0]), "|"); + } + } + +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/README.mustache b/generator/cybersource-java-template/libraries/retrofit2/README.mustache new file mode 100644 index 000000000..9d744b858 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/README.mustache @@ -0,0 +1,39 @@ +# {{artifactId}} + +## Requirements + +Building the API client library requires [Maven](https://maven.apache.org/) to be installed. + +## Installation & Usage + +To install the API client library to your local Maven repository, simply execute: + +```shell +mvn install +``` + +To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: + +```shell +mvn deploy +``` + +Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information. + +After the client library is installed/deployed, you can use it in your Maven project by adding the following to your *pom.xml*: + +```xml + + {{groupId}} + {{artifactId}} + {{artifactVersion}} + compile + + +``` + +## Author + +{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}} +{{/hasMore}}{{/apis}}{{/apiInfo}} + diff --git a/generator/cybersource-java-template/libraries/retrofit2/api.mustache b/generator/cybersource-java-template/libraries/retrofit2/api.mustache new file mode 100644 index 000000000..98d511179 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/api.mustache @@ -0,0 +1,59 @@ +package {{package}}; + +import {{invokerPackage}}.CollectionFormats.*; + +{{#useRxJava}}import rx.Observable;{{/useRxJava}} +{{#useRxJava2}}import io.reactivex.Observable;{{/useRxJava2}} +{{#doNotUseRx}}import retrofit2.Call;{{/doNotUseRx}} +import retrofit2.http.*; + +import okhttp3.RequestBody; + +{{#imports}}import {{import}}; +{{/imports}} + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +{{#usePlay24WS}} +import play.libs.F; +import retrofit2.Response; +{{/usePlay24WS}} + +{{#operations}} +public interface {{classname}} { + {{#operation}} + /** + * {{summary}} + * {{notes}} +{{#allParams}} + * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} +{{/allParams}} + * @return Call<{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object{{/returnType}}> + */ + {{#formParams}} + {{#-first}} + {{#isMultipart}}@retrofit2.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit2.http.FormUrlEncoded{{/isMultipart}} + {{/-first}} + {{/formParams}} + {{^formParams}} + {{#prioritizedContentTypes}} + {{#-first}} + @Headers({ + "Content-Type:{{mediaType}}" + }) + {{/-first}} + {{/prioritizedContentTypes}} + {{/formParams}} + @{{httpMethod}}("{{{path}}}") + {{^usePlay24WS}}{{^doNotUseRx}}Observable{{/doNotUseRx}}{{#doNotUseRx}}Call{{/doNotUseRx}}{{/usePlay24WS}}{{#usePlay24WS}}F.Promise{{#usePlay24WS}}>{{/usePlay24WS}} {{operationId}}({{^allParams}});{{/allParams}} + {{#allParams}}{{>libraries/retrofit2/queryParams}}{{>libraries/retrofit2/pathParams}}{{>libraries/retrofit2/headerParams}}{{>libraries/retrofit2/bodyParams}}{{>libraries/retrofit2/formParams}}{{#hasMore}}, {{/hasMore}}{{^hasMore}} + );{{/hasMore}}{{/allParams}} + + {{/operation}} +} +{{/operations}} diff --git a/generator/cybersource-java-template/libraries/retrofit2/api_test.mustache b/generator/cybersource-java-template/libraries/retrofit2/api_test.mustache new file mode 100644 index 000000000..a34cfe0e1 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/api_test.mustache @@ -0,0 +1,44 @@ +package {{package}}; + +import {{invokerPackage}}.ApiClient; +{{#imports}}import {{import}}; +{{/imports}} +import org.junit.Before; +import org.junit.Test; + +{{^fullJavaUtil}} +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +{{/fullJavaUtil}} + +/** + * API tests for {{classname}} + */ +public class {{classname}}Test { + + private {{classname}} api; + + @Before + public void setup() { + api = new ApiClient().createService({{classname}}.class); + } + + {{#operations}}{{#operation}} + /** + * {{summary}} + * + * {{notes}} + */ + @Test + public void {{operationId}}Test() { + {{#allParams}} + {{{dataType}}} {{paramName}} = null; + {{/allParams}} + // {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + + // TODO: test validations + } + {{/operation}}{{/operations}} +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/auth/ApiKeyAuth.mustache b/generator/cybersource-java-template/libraries/retrofit2/auth/ApiKeyAuth.mustache new file mode 100644 index 000000000..2f4bae3dd --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/auth/ApiKeyAuth.mustache @@ -0,0 +1,68 @@ +package {{invokerPackage}}.auth; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +public class ApiKeyAuth implements Interceptor { + private final String location; + private final String paramName; + + private String apiKey; + + public ApiKeyAuth(String location, String paramName) { + this.location = location; + this.paramName = paramName; + } + + public String getLocation() { + return location; + } + + public String getParamName() { + return paramName; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + @Override + public Response intercept(Chain chain) throws IOException { + String paramValue; + Request request = chain.request(); + + if ("query".equals(location)) { + String newQuery = request.url().uri().getQuery(); + paramValue = paramName + "=" + apiKey; + if (newQuery == null) { + newQuery = paramValue; + } else { + newQuery += "&" + paramValue; + } + + URI newUri; + try { + newUri = new URI(request.url().uri().getScheme(), request.url().uri().getAuthority(), + request.url().uri().getPath(), newQuery, request.url().uri().getFragment()); + } catch (URISyntaxException e) { + throw new IOException(e); + } + + request = request.newBuilder().url(newUri.toURL()).build(); + } else if ("header".equals(location)) { + request = request.newBuilder() + .addHeader(paramName, apiKey) + .build(); + } + return chain.proceed(request); + } +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/auth/HttpBasicAuth.mustache b/generator/cybersource-java-template/libraries/retrofit2/auth/HttpBasicAuth.mustache new file mode 100644 index 000000000..d45884266 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/auth/HttpBasicAuth.mustache @@ -0,0 +1,50 @@ +package {{invokerPackage}}.auth; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.Credentials; + +public class HttpBasicAuth implements Interceptor { + + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setCredentials(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + + // If the request already have an authorization (eg. Basic auth), do nothing + if (request.header("Authorization") == null) { + String credentials = Credentials.basic(username, password); + request = request.newBuilder() + .addHeader("Authorization", credentials) + .build(); + } + return chain.proceed(request); + } +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/auth/OAuth.mustache b/generator/cybersource-java-template/libraries/retrofit2/auth/OAuth.mustache new file mode 100644 index 000000000..bb070d484 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/auth/OAuth.mustache @@ -0,0 +1,176 @@ +package {{invokerPackage}}.auth; + +import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; +import static java.net.HttpURLConnection.HTTP_FORBIDDEN; + +import java.io.IOException; +import java.util.Map; + +import org.apache.oltu.oauth2.client.OAuthClient; +import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; +import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse; +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; +import org.apache.oltu.oauth2.common.exception.OAuthSystemException; +import org.apache.oltu.oauth2.common.message.types.GrantType; +import org.apache.oltu.oauth2.common.token.BasicOAuthToken; + +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Request.Builder; +import okhttp3.Response; + +public class OAuth implements Interceptor { + + public interface AccessTokenListener { + public void notify(BasicOAuthToken token); + } + + private volatile String accessToken; + private OAuthClient oauthClient; + + private TokenRequestBuilder tokenRequestBuilder; + private AuthenticationRequestBuilder authenticationRequestBuilder; + + private AccessTokenListener accessTokenListener; + + public OAuth( OkHttpClient client, TokenRequestBuilder requestBuilder ) { + this.oauthClient = new OAuthClient(new OAuthOkHttpClient(client)); + this.tokenRequestBuilder = requestBuilder; + } + + public OAuth(TokenRequestBuilder requestBuilder ) { + this(new OkHttpClient(), requestBuilder); + } + + public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) { + this(OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes)); + setFlow(flow); + authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl); + } + + public void setFlow(OAuthFlow flow) { + switch(flow) { + case accessCode: + case implicit: + tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE); + break; + case password: + tokenRequestBuilder.setGrantType(GrantType.PASSWORD); + break; + case application: + tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS); + break; + default: + break; + } + } + + @Override + public Response intercept(Chain chain) + throws IOException { + + Request request = chain.request(); + + // If the request already have an authorization (eg. Basic auth), do nothing + if (request.header("Authorization") != null) { + return chain.proceed(request); + } + + // If first time, get the token + OAuthClientRequest oAuthRequest; + if (getAccessToken() == null) { + updateAccessToken(null); + } + + if (getAccessToken() != null) { + // Build the request + Builder rb = request.newBuilder(); + + String requestAccessToken = new String(getAccessToken()); + try { + oAuthRequest = new OAuthBearerClientRequest(request.url().toString()) + .setAccessToken(requestAccessToken) + .buildHeaderMessage(); + } catch (OAuthSystemException e) { + throw new IOException(e); + } + + for ( Map.Entry header : oAuthRequest.getHeaders().entrySet() ) { + rb.addHeader(header.getKey(), header.getValue()); + } + rb.url( oAuthRequest.getLocationUri()); + + //Execute the request + Response response = chain.proceed(rb.build()); + + // 401 most likely indicates that access token has expired. + // Time to refresh and resend the request + if ( response != null && (response.code() == HTTP_UNAUTHORIZED | response.code() == HTTP_FORBIDDEN) ) { + if (updateAccessToken(requestAccessToken)) { + return intercept( chain ); + } + } + return response; + } else { + return chain.proceed(chain.request()); + } + } + + /* + * Returns true if the access token has been updated + */ + public synchronized boolean updateAccessToken(String requestAccessToken) throws IOException { + if (getAccessToken() == null || getAccessToken().equals(requestAccessToken)) { + try { + OAuthJSONAccessTokenResponse accessTokenResponse = oauthClient.accessToken(this.tokenRequestBuilder.buildBodyMessage()); + if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) { + setAccessToken(accessTokenResponse.getAccessToken()); + if (accessTokenListener != null) { + accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken()); + } + return !getAccessToken().equals(requestAccessToken); + } else { + return false; + } + } catch (OAuthSystemException e) { + throw new IOException(e); + } catch (OAuthProblemException e) { + throw new IOException(e); + } + } + return true; + } + + public void registerAccessTokenListener(AccessTokenListener accessTokenListener) { + this.accessTokenListener = accessTokenListener; + } + + public synchronized String getAccessToken() { + return accessToken; + } + + public synchronized void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public TokenRequestBuilder getTokenRequestBuilder() { + return tokenRequestBuilder; + } + + public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) { + this.tokenRequestBuilder = tokenRequestBuilder; + } + + public AuthenticationRequestBuilder getAuthenticationRequestBuilder() { + return authenticationRequestBuilder; + } + + public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) { + this.authenticationRequestBuilder = authenticationRequestBuilder; + } + +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/auth/OAuthOkHttpClient.mustache b/generator/cybersource-java-template/libraries/retrofit2/auth/OAuthOkHttpClient.mustache new file mode 100644 index 000000000..423fa1ba0 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/auth/OAuthOkHttpClient.mustache @@ -0,0 +1,72 @@ +package {{invokerPackage}}.auth; + +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.oltu.oauth2.client.HttpClient; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest; +import org.apache.oltu.oauth2.client.response.OAuthClientResponse; +import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory; +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; +import org.apache.oltu.oauth2.common.exception.OAuthSystemException; + + +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Request.Builder; +import okhttp3.Response; +import okhttp3.MediaType; +import okhttp3.RequestBody; + + +public class OAuthOkHttpClient implements HttpClient { + + private OkHttpClient client; + + public OAuthOkHttpClient() { + this.client = new OkHttpClient(); + } + + public OAuthOkHttpClient(OkHttpClient client) { + this.client = client; + } + + public T execute(OAuthClientRequest request, Map headers, + String requestMethod, Class responseClass) + throws OAuthSystemException, OAuthProblemException { + + MediaType mediaType = MediaType.parse("application/json"); + Request.Builder requestBuilder = new Request.Builder().url(request.getLocationUri()); + + if(headers != null) { + for (Entry entry : headers.entrySet()) { + if (entry.getKey().equalsIgnoreCase("Content-Type")) { + mediaType = MediaType.parse(entry.getValue()); + } else { + requestBuilder.addHeader(entry.getKey(), entry.getValue()); + } + } + } + + RequestBody body = request.getBody() != null ? RequestBody.create(mediaType, request.getBody()) : null; + requestBuilder.method(requestMethod, body); + + try { + Response response = client.newCall(requestBuilder.build()).execute(); + return OAuthClientResponseFactory.createCustomResponse( + response.body().string(), + response.body().contentType().toString(), + response.code(), + responseClass); + } catch (IOException e) { + throw new OAuthSystemException(e); + } + } + + public void shutdown() { + // Nothing to do here + } + +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/bodyParams.mustache b/generator/cybersource-java-template/libraries/retrofit2/bodyParams.mustache new file mode 100644 index 000000000..97b03fcb7 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/bodyParams.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}@retrofit2.http.Body {{{dataType}}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit2/build.gradle.mustache b/generator/cybersource-java-template/libraries/retrofit2/build.gradle.mustache new file mode 100644 index 000000000..9e0ad8a57 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/build.gradle.mustache @@ -0,0 +1,151 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' + +group = '{{groupId}}' +version = '{{artifactVersion}}' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + } +} + +repositories { + jcenter() +} + + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 25 + } + compileOptions { + {{#java8}} + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + {{/java8}} + {{^java8}} + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + {{/java8}} + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + + sourceCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} + targetCompatibility = JavaVersion.VERSION_{{^java8}}1_7{{/java8}}{{#java8}}1_8{{/java8}} + + install { + repositories.mavenInstaller { + pom.artifactId = '{{artifactId}}' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +ext { + oltu_version = "1.0.1" + {{^usePlay24WS}} + retrofit_version = "2.3.0" + {{/usePlay24WS}} + {{#usePlay24WS}} + retrofit_version = "2.1.0" + jackson_version = "2.8.9" + play_version = "2.4.11" + {{/usePlay24WS}} + swagger_annotations_version = "1.5.15" + junit_version = "4.12" + {{#useRxJava}} + rx_java_version = "1.3.0" + {{/useRxJava}} + {{#useRxJava2}} + rx_java_version = "2.1.1" + {{/useRxJava2}} + {{^java8}} + jodatime_version = "2.9.9" + {{/java8}} +} + +dependencies { + compile "com.squareup.retrofit2:retrofit:$retrofit_version" + compile "com.squareup.retrofit2:converter-scalars:$retrofit_version" + compile "com.squareup.retrofit2:converter-gson:$retrofit_version" + {{#useRxJava}} + compile "com.squareup.retrofit2:adapter-rxjava:$retrofit_version" + compile "io.reactivex:rxjava:$rx_java_version" + {{/useRxJava}} + {{#useRxJava2}} + compile "com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0" + compile "io.reactivex.rxjava2:rxjava:$rx_java_version" + {{/useRxJava2}} + compile "io.swagger:swagger-annotations:$swagger_annotations_version" + compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version" + {{^java8}} + compile "joda-time:joda-time:$jodatime_version" + {{/java8}} + {{#usePlay24WS}} + compile "com.typesafe.play:play-java-ws_2.11:$play_version" + compile "com.squareup.retrofit2:converter-jackson:$retrofit_version" + compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" + compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" + compile "com.fasterxml.jackson.datatype:jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}:$jackson_version" + {{/usePlay24WS}} + + testCompile "junit:junit:$junit_version" +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/build.sbt.mustache b/generator/cybersource-java-template/libraries/retrofit2/build.sbt.mustache new file mode 100644 index 000000000..2146acd49 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/build.sbt.mustache @@ -0,0 +1,43 @@ +lazy val root = (project in file(".")). + settings( + organization := "{{groupId}}", + name := "{{artifactId}}", + version := "{{artifactVersion}}", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + {{^usePlay24WS}} + "com.squareup.retrofit2" % "retrofit" % "2.3.0" % "compile", + "com.squareup.retrofit2" % "converter-scalars" % "2.3.0" % "compile", + "com.squareup.retrofit2" % "converter-gson" % "2.3.0" % "compile", + {{/usePlay24WS}} + {{#usePlay24WS}} + "com.typesafe.play" % "play-java-ws_2.11" % "2.4.11" % "compile", + "com.squareup.retrofit2" % "retrofit" % "2.1.0" % "compile", + "com.squareup.retrofit2" % "converter-scalars" % "2.1.0" % "compile", + "com.squareup.retrofit2" % "converter-gson" % "2.1.0" % "compile", + "com.squareup.retrofit2" % "converter-jackson" % "2.1.0" % "compile", + "com.fasterxml.jackson.core" % "jackson-core" % "2.8.9" % "compile", + "com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.9" % "compile", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.8.9" % "compile", + {{/usePlay24WS}} + {{#useRxJava}} + "com.squareup.retrofit2" % "adapter-rxjava" % "{{^usePlay24WS}}2.2.0{{/usePlay24WS}}{{#usePlay24WS}}2.1.0{{/usePlay24WS}}" % "compile", + "io.reactivex" % "rxjava" % "1.3.0" % "compile", + {{/useRxJava}} + {{#useRxJava2}} + "com.jakewharton.retrofit" % "retrofit2-rxjava2-adapter" % "1.0.0" % "compile", + "io.reactivex.rxjava2" % "rxjava" % "2.1.1" % "compile", + {{/useRxJava2}} + "io.swagger" % "swagger-annotations" % "1.5.15" % "compile", + "org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile", + {{^java8}} + "joda-time" % "joda-time" % "2.9.9" % "compile", + {{/java8}} + "junit" % "junit" % "4.12" % "test", + "com.novocode" % "junit-interface" % "0.11" % "test" + ) + ) diff --git a/generator/cybersource-java-template/libraries/retrofit2/formParams.mustache b/generator/cybersource-java-template/libraries/retrofit2/formParams.mustache new file mode 100644 index 000000000..2e237383e --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/formParams.mustache @@ -0,0 +1 @@ +{{#isFormParam}}{{#notFile}}{{#isMultipart}}@retrofit2.http.Part{{/isMultipart}}{{^isMultipart}}@retrofit2.http.Field{{/isMultipart}}("{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@retrofit2.http.Part{{/isMultipart}}{{^isMultipart}}@retrofit2.http.Field{{/isMultipart}}("{{baseName}}\"; filename=\"{{baseName}}") RequestBody {{paramName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit2/formParams.mustache.save b/generator/cybersource-java-template/libraries/retrofit2/formParams.mustache.save new file mode 100644 index 000000000..a203e99a2 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/formParams.mustache.save @@ -0,0 +1 @@ +{{#isFormParam}}{{#notFile}}{{#isMultipart}}retrofit.http@retrofit2.http.Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{baseName}}\"; filename=\"{{baseName}}") RequestBody {{paramName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit2/headerParams.mustache b/generator/cybersource-java-template/libraries/retrofit2/headerParams.mustache new file mode 100644 index 000000000..c7748f3bf --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/headerParams.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}@retrofit2.http.Header("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit2/pathParams.mustache b/generator/cybersource-java-template/libraries/retrofit2/pathParams.mustache new file mode 100644 index 000000000..8fe7c380c --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/pathParams.mustache @@ -0,0 +1 @@ +{{#isPathParam}}@retrofit2.http.Path("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/libraries/retrofit2/play24/ApiClient.mustache b/generator/cybersource-java-template/libraries/retrofit2/play24/ApiClient.mustache new file mode 100644 index 000000000..5c871c620 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/play24/ApiClient.mustache @@ -0,0 +1,136 @@ +package {{invokerPackage}}; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.*; + +import retrofit2.Retrofit; +import retrofit2.converter.scalars.ScalarsConverterFactory; +import retrofit2.converter.jackson.JacksonConverterFactory; + +import play.libs.Json; +import play.libs.ws.WSClient; + +import {{invokerPackage}}.Play24CallAdapterFactory; +import {{invokerPackage}}.Play24CallFactory; + +import okhttp3.Interceptor; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.Authentication; + +/** + * API client + */ +public class ApiClient { + + /** Underlying HTTP-client */ + private WSClient wsClient; + + /** Supported auths */ + private Map authentications; + + /** API base path */ + private String basePath = "{{{basePath}}}"; + + public ApiClient(WSClient wsClient) { + this(); + this.wsClient = wsClient; + } + + public ApiClient() { + // Setup authentications (key: authentication name, value: authentication). + authentications = new HashMap<>();{{#authMethods}}{{#isBasic}} + // authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}} + authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}} + // authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}} + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + + } + + /** + * Creates a retrofit2 client for given API interface + */ + public S createService(Class serviceClass) { + if(!basePath.endsWith("/")) { + basePath = basePath + "/"; + } + + Map extraHeaders = new HashMap<>(); + List extraQueryParams = new ArrayList<>(); + + for (String authName : authentications.keySet()) { + Authentication auth = authentications.get(authName); + if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); + + auth.applyToParams(extraQueryParams, extraHeaders); + } + + return new Retrofit.Builder() + .baseUrl(basePath) + .addConverterFactory(ScalarsConverterFactory.create()) + .addConverterFactory(JacksonConverterFactory.create(Json.mapper())) + .callFactory(new Play24CallFactory(wsClient, extraHeaders, extraQueryParams)) + .addCallAdapterFactory(new Play24CallAdapterFactory()) + .build() + .create(serviceClass); + } + + /** + * Helper method to set API base path + */ + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Get authentications (key: authentication name, value: authentication). + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set API key value for the first API key authentication. + */ + public ApiClient setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return this; + } + } + + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + */ + public ApiClient setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return this; + } + } + + throw new RuntimeException("No API key authentication configured!"); + } + + +} + + diff --git a/generator/cybersource-java-template/libraries/retrofit2/play24/Play24CallAdapterFactory.mustache b/generator/cybersource-java-template/libraries/retrofit2/play24/Play24CallAdapterFactory.mustache new file mode 100644 index 000000000..89fca2613 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/play24/Play24CallAdapterFactory.mustache @@ -0,0 +1,90 @@ +package {{invokerPackage}}; + +import play.libs.F; +import retrofit2.*; + +import java.lang.annotation.Annotation; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.WildcardType; + +/** + * Creates {@link CallAdapter} instances that convert {@link Call} into {@link play.libs.F.Promise} + */ +public class Play24CallAdapterFactory extends CallAdapter.Factory { + + @Override + public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + if (!(returnType instanceof ParameterizedType)) { + return null; + } + + ParameterizedType type = (ParameterizedType) returnType; + if (type.getRawType() != F.Promise.class) { + return null; + } + + return createAdapter((ParameterizedType) returnType); + } + + private Type getTypeParam(ParameterizedType type) { + Type[] types = type.getActualTypeArguments(); + if (types.length != 1) { + throw new IllegalStateException("Must be exactly one type parameter"); + } + + Type paramType = types[0]; + if (paramType instanceof WildcardType) { + return ((WildcardType) paramType).getUpperBounds()[0]; + } + + return paramType; + } + + private CallAdapter> createAdapter(ParameterizedType returnType) { + Type parameterType = getTypeParam(returnType); + return new ValueAdapter(parameterType); + } + + /** + * Adpater that coverts values returned by API interface into Play promises + */ + static final class ValueAdapter implements CallAdapter> { + + private final Type responseType; + + ValueAdapter(Type responseType) { + this.responseType = responseType; + } + + @Override + public Type responseType() { + return responseType; + } + + @Override + public F.Promise adapt(final Call call) { + final F.RedeemablePromise promise = F.RedeemablePromise.empty(); + + call.enqueue(new Callback() { + + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + promise.success(response.body()); + } else { + promise.failure(new Exception(response.errorBody().toString())); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + promise.failure(t); + } + + }); + + return promise; + } + } +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/play24/Play24CallFactory.mustache b/generator/cybersource-java-template/libraries/retrofit2/play24/Play24CallFactory.mustache new file mode 100644 index 000000000..62df91f79 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/play24/Play24CallFactory.mustache @@ -0,0 +1,215 @@ +package {{invokerPackage}}; + +import okhttp3.*; +import okio.Buffer; +import okio.BufferedSource; +import play.libs.F; +import play.libs.ws.WSClient; +import play.libs.ws.WSRequest; +import play.libs.ws.WSResponse; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Creates {@link Call} instances that invoke underlying {@link WSClient} + */ +public class Play24CallFactory implements okhttp3.Call.Factory { + + /** PlayWS http client */ + private final WSClient wsClient; + + /** Extra headers to add to request */ + private Map extraHeaders = new HashMap<>(); + + /** Extra query parameters to add to request */ + private List extraQueryParams = new ArrayList<>(); + + public Play24CallFactory(WSClient wsClient) { + this.wsClient = wsClient; + } + + public Play24CallFactory(WSClient wsClient, Map extraHeaders, + List extraQueryParams) { + this.wsClient = wsClient; + + this.extraHeaders.putAll(extraHeaders); + this.extraQueryParams.addAll(extraQueryParams); + } + + @Override + public Call newCall(Request request) { + // add extra headers + Request.Builder rb = request.newBuilder(); + for (Map.Entry header : this.extraHeaders.entrySet()) { + rb.addHeader(header.getKey(), header.getValue()); + } + + // add extra query params + if (!this.extraQueryParams.isEmpty()) { + String newQuery = request.url().uri().getQuery(); + for (Pair queryParam : this.extraQueryParams) { + String param = String.format("%s=%s", queryParam.getName(), queryParam.getValue()); + if (newQuery == null) { + newQuery = param; + } else { + newQuery += "&" + param; + } + } + + URI newUri; + try { + newUri = new URI(request.url().uri().getScheme(), request.url().uri().getAuthority(), + request.url().uri().getPath(), newQuery, request.url().uri().getFragment()); + rb.url(newUri.toURL()); + } catch (MalformedURLException | URISyntaxException e) { + throw new RuntimeException("Error while updating an url", e); + } + } + + return new PlayWSCall(wsClient, rb.build()); + } + + /** + * Call implementation that delegates to Play WS Client + */ + static class PlayWSCall implements Call { + + private final WSClient wsClient; + private WSRequest wsRequest; + + private final Request request; + + public PlayWSCall(WSClient wsClient, Request request) { + this.wsClient = wsClient; + this.request = request; + } + + @Override + public Request request() { + return request; + } + + @Override + public void enqueue(final okhttp3.Callback responseCallback) { + final Call call = this; + final F.Promise promise = executeAsync(); + + promise.onRedeem(new F.Callback() { + + @Override + public void invoke(WSResponse wsResponse) throws Throwable { + responseCallback.onResponse(call, PlayWSCall.this.toWSResponse(wsResponse)); + } + + }); + + promise.onFailure(new F.Callback() { + + @Override + public void invoke(Throwable throwable) throws Throwable { + if (throwable instanceof IOException) { + responseCallback.onFailure(call, (IOException) throwable); + } else { + responseCallback.onFailure(call, new IOException(throwable)); + } + } + + }); + + } + + F.Promise executeAsync() { + try { + wsRequest = wsClient.url(request.url().uri().toString()); + addHeaders(wsRequest); + if (request.body() != null) { + addBody(wsRequest); + } + + return wsRequest.execute(request.method()); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + private void addHeaders(WSRequest wsRequest) { + for(Map.Entry> entry : request.headers().toMultimap().entrySet()) { + List values = entry.getValue(); + for (String value : values) { + wsRequest.setHeader(entry.getKey(), value); + } + } + } + + private void addBody(WSRequest wsRequest) throws IOException { + Buffer buffer = new Buffer(); + request.body().writeTo(buffer); + wsRequest.setBody(buffer.inputStream()); + wsRequest.setContentType(request.body().contentType().toString()); + } + + private Response toWSResponse(final WSResponse r) { + final Response.Builder builder = new Response.Builder(); + builder.request(request) + .code(r.getStatus()) + .body(new ResponseBody() { + + @Override + public MediaType contentType() { + return MediaType.parse(r.getHeader("Content-Type")); + } + + @Override + public long contentLength() { + return r.getBody().getBytes().length; + } + + @Override + public BufferedSource source() { + return new Buffer().write(r.getBody().getBytes()); + } + }); + + for (Map.Entry> entry : r.getAllHeaders().entrySet()) { + for (String value : entry.getValue()) { + builder.addHeader(entry.getKey(), value); + } + } + + builder.protocol(Protocol.HTTP_1_1); + return builder.build(); + } + + @Override + public Response execute() throws IOException { + throw new UnsupportedOperationException("Not supported"); + } + + @Override + public void cancel() { + throw new UnsupportedOperationException("Not supported"); + } + + @Override + public PlayWSCall clone() { + throw new UnsupportedOperationException("Not supported"); + } + + @Override + public boolean isExecuted() { + return false; + } + + @Override + public boolean isCanceled() { + return false; + } + } +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/play24/auth/ApiKeyAuth.mustache b/generator/cybersource-java-template/libraries/retrofit2/play24/auth/ApiKeyAuth.mustache new file mode 100644 index 000000000..5652db326 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/play24/auth/ApiKeyAuth.mustache @@ -0,0 +1,67 @@ +{{>licenseInfo}} + +package {{invokerPackage}}.auth; + +import {{invokerPackage}}.Pair; + +import java.util.Map; +import java.util.List; + +/** + * Holds ApiKey auth info + */ +{{>generatedAnnotation}} +public class ApiKeyAuth implements Authentication { + private final String location; + private final String paramName; + + private String apiKey; + private String apiKeyPrefix; + + public ApiKeyAuth(String location, String paramName) { + this.location = location; + this.paramName = paramName; + } + + public String getLocation() { + return location; + } + + public String getParamName() { + return paramName; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getApiKeyPrefix() { + return apiKeyPrefix; + } + + public void setApiKeyPrefix(String apiKeyPrefix) { + this.apiKeyPrefix = apiKeyPrefix; + } + + @Override + public void applyToParams(List queryParams, Map headerParams) { + if (apiKey == null) { + return; + } + String value; + if (apiKeyPrefix != null) { + value = apiKeyPrefix + " " + apiKey; + } else { + value = apiKey; + } + if ("query".equals(location)) { + queryParams.add(new Pair(paramName, value)); + } else if ("header".equals(location)) { + headerParams.put(paramName, value); + } + } +} diff --git a/generator/cybersource-java-template/libraries/retrofit2/pom.mustache b/generator/cybersource-java-template/libraries/retrofit2/pom.mustache new file mode 100644 index 000000000..d99337168 --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/pom.mustache @@ -0,0 +1,314 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + 2.2.0 + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-core-version} + + + com.squareup.retrofit2 + converter-gson + ${retrofit-version} + + + com.squareup.retrofit2 + retrofit + ${retrofit-version} + + + com.squareup.retrofit2 + converter-scalars + ${retrofit-version} + + + org.apache.oltu.oauth2 + org.apache.oltu.oauth2.client + ${oltu-version} + + {{^java8}} + + joda-time + joda-time + ${jodatime-version} + + {{/java8}} + {{#useRxJava}} + + io.reactivex + rxjava + ${rxjava-version} + + + com.squareup.retrofit2 + adapter-rxjava + ${retrofit-version} + + {{/useRxJava}} + {{#useRxJava2}} + + io.reactivex.rxjava2 + rxjava + ${rxjava-version} + + + com.jakewharton.retrofit + retrofit2-rxjava2-adapter + 1.0.0 + + {{/useRxJava2}} + + {{#usePlay24WS}} + + + com.squareup.retrofit2 + converter-jackson + ${retrofit-version} + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + + com.fasterxml.jackson.datatype + jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}} + ${jackson-version} + + {{#withXml}} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson-version} + + + {{/withXml}} + + com.typesafe.play + play-java-ws_2.11 + ${play-version} + + {{/usePlay24WS}} + + {{#parcelableModel}} + + + com.google.android + android + 4.1.1.4 + provided + + {{/parcelableModel}} + + + + junit + junit + ${junit-version} + test + + + + UTF-8 + {{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}} + ${java.version} + ${java.version} + 1.5.15 + {{#usePlay24WS}} + 2.8.9 + 2.4.11 + {{/usePlay24WS}} + 2.3.0 + {{#useRxJava}} + 1.3.0 + {{/useRxJava}} + {{#useRxJava2}} + 2.1.1 + {{/useRxJava2}} + {{^java8}} + 2.9.9 + {{/java8}} + 1.0.1 + 4.12 + + diff --git a/generator/cybersource-java-template/libraries/retrofit2/queryParams.mustache b/generator/cybersource-java-template/libraries/retrofit2/queryParams.mustache new file mode 100644 index 000000000..abb87510e --- /dev/null +++ b/generator/cybersource-java-template/libraries/retrofit2/queryParams.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}@retrofit2.http.Query("{{baseName}}") {{#collectionFormat}}{{#isCollectionFormatMulti}}{{{dataType}}}{{/isCollectionFormatMulti}}{{^isCollectionFormatMulti}}{{{collectionFormat.toUpperCase}}}Params{{/isCollectionFormatMulti}}{{/collectionFormat}}{{^collectionFormat}}{{{dataType}}}{{/collectionFormat}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/generator/cybersource-java-template/licenseInfo.mustache b/generator/cybersource-java-template/licenseInfo.mustache new file mode 100644 index 000000000..94c36dda3 --- /dev/null +++ b/generator/cybersource-java-template/licenseInfo.mustache @@ -0,0 +1,11 @@ +/* + * {{{appName}}} + * {{{appDescription}}} + * + * {{#version}}OpenAPI spec version: {{{version}}}{{/version}} + * {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}} + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ diff --git a/generator/cybersource-java-template/manifest.mustache b/generator/cybersource-java-template/manifest.mustache new file mode 100644 index 000000000..f44bd07d0 --- /dev/null +++ b/generator/cybersource-java-template/manifest.mustache @@ -0,0 +1,3 @@ + + + diff --git a/generator/cybersource-java-template/model.mustache b/generator/cybersource-java-template/model.mustache new file mode 100644 index 000000000..a0fb114b7 --- /dev/null +++ b/generator/cybersource-java-template/model.mustache @@ -0,0 +1,39 @@ +{{>licenseInfo}} + +package {{package}}; + +{{^supportJava6}} +import java.util.Objects; +{{/supportJava6}} +{{#supportJava6}} +import org.apache.commons.lang3.ObjectUtils; +{{/supportJava6}} +{{#imports}} +import {{import}}; +{{/imports}} +{{#serializableModel}} +import java.io.Serializable; +{{/serializableModel}} +{{#jackson}} +{{#withXml}} +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +{{/withXml}} +{{/jackson}} +{{#withXml}} +import javax.xml.bind.annotation.*; +{{/withXml}} +{{#parcelableModel}} +import android.os.Parcelable; +import android.os.Parcel; +{{/parcelableModel}} +{{#useBeanValidation}} +import javax.validation.constraints.*; +import javax.validation.Valid; +{{/useBeanValidation}} + +{{#models}} +{{#model}} +{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>pojo}}{{/isEnum}} +{{/model}} +{{/models}} diff --git a/generator/cybersource-java-template/modelEnum.mustache b/generator/cybersource-java-template/modelEnum.mustache new file mode 100644 index 000000000..209d31017 --- /dev/null +++ b/generator/cybersource-java-template/modelEnum.mustache @@ -0,0 +1,68 @@ +{{#jackson}} +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +{{/jackson}} +{{#gson}} +import java.io.IOException; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +{{/gson}} + +/** + * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} + */ +{{#gson}} +@JsonAdapter({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.Adapter.class) +{{/gson}} +public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} { + {{#allowableValues}}{{#enumVars}} + {{{name}}}({{{value}}}){{^-last}}, + {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}} + + private {{{dataType}}} value; + + {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) { + this.value = value; + } + +{{#jackson}} + @JsonValue +{{/jackson}} + public {{{dataType}}} getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + +{{#jackson}} + @JsonCreator +{{/jackson}} + public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) { + for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } +{{#gson}} + + public static class Adapter extends TypeAdapter<{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}> { + @Override + public void write(final JsonWriter jsonWriter, final {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} enumeration) throws IOException { + jsonWriter.value(enumeration.getValue()); + } + + @Override + public {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException { + {{{dataType}}} value = jsonReader.{{#isInteger}}nextInt(){{/isInteger}}{{^isInteger}}next{{{dataType}}}(){{/isInteger}}; + return {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue(String.valueOf(value)); + } + } +{{/gson}} +} diff --git a/generator/cybersource-java-template/modelInnerEnum.mustache b/generator/cybersource-java-template/modelInnerEnum.mustache new file mode 100644 index 000000000..e7ffa65d1 --- /dev/null +++ b/generator/cybersource-java-template/modelInnerEnum.mustache @@ -0,0 +1,59 @@ + /** + * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} + */ +{{#gson}} + @JsonAdapter({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}.Adapter.class) +{{/gson}} + public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { + {{#allowableValues}} + {{#enumVars}} + {{{name}}}({{{value}}}){{^-last}}, + {{/-last}}{{#-last}};{{/-last}} + {{/enumVars}} + {{/allowableValues}} + + private {{{datatype}}} value; + + {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{datatype}}} value) { + this.value = value; + } + +{{#jackson}} + @JsonValue +{{/jackson}} + public {{{datatype}}} getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + +{{#jackson}} + @JsonCreator +{{/jackson}} + public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) { + for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } +{{#gson}} + + public static class Adapter extends TypeAdapter<{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}> { + @Override + public void write(final JsonWriter jsonWriter, final {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} enumeration) throws IOException { + jsonWriter.value(enumeration.getValue()); + } + + @Override + public {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException { + {{{datatype}}} value = jsonReader.{{#isInteger}}nextInt(){{/isInteger}}{{^isInteger}}next{{{datatype}}}(){{/isInteger}}; + return {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}.fromValue(String.valueOf(value)); + } + } +{{/gson}} + } diff --git a/generator/cybersource-java-template/model_doc.mustache b/generator/cybersource-java-template/model_doc.mustache new file mode 100644 index 000000000..658df8d53 --- /dev/null +++ b/generator/cybersource-java-template/model_doc.mustache @@ -0,0 +1,3 @@ +{{#models}}{{#model}} +{{#isEnum}}{{>enum_outer_doc}}{{/isEnum}}{{^isEnum}}{{>pojo_doc}}{{/isEnum}} +{{/model}}{{/models}} diff --git a/generator/cybersource-java-template/pojo.mustache b/generator/cybersource-java-template/pojo.mustache new file mode 100644 index 000000000..d0a4c70f3 --- /dev/null +++ b/generator/cybersource-java-template/pojo.mustache @@ -0,0 +1,214 @@ +/** + * {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} + */{{#description}} +@ApiModel(description = "{{{description}}}"){{/description}} +{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} +public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcelableModel}}implements Parcelable {{#serializableModel}}, Serializable {{/serializableModel}}{{/parcelableModel}}{{^parcelableModel}}{{#serializableModel}}implements Serializable {{/serializableModel}}{{/parcelableModel}}{ +{{#serializableModel}} + private static final long serialVersionUID = 1L; + +{{/serializableModel}} + {{#vars}} + {{#isEnum}} + {{^isContainer}} +{{>modelInnerEnum}} + {{/isContainer}} + {{/isEnum}} + {{#items.isEnum}} + {{#items}} + {{^isContainer}} +{{>modelInnerEnum}} + {{/isContainer}} + {{/items}} + {{/items.isEnum}} + {{#jackson}} + @JsonProperty("{{baseName}}") + {{#withXml}} + @JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") + {{/withXml}} + {{/jackson}} + {{#withXml}} + {{#isXmlAttribute}} + @XmlAttribute(name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") + {{/isXmlAttribute}} + {{^isXmlAttribute}} + @XmlElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") + {{/isXmlAttribute}} + {{/withXml}} + {{#gson}} + @SerializedName("{{baseName}}") + {{/gson}} + {{#isContainer}} + private {{{datatypeWithEnum}}} {{name}}{{#required}} = {{{defaultValue}}}{{/required}}{{^required}} = null{{/required}}; + {{/isContainer}} + {{^isContainer}} + private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}}; + {{/isContainer}} + + {{/vars}} + {{#vars}} + {{^isReadOnly}} + public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { + this.{{name}} = {{name}}; + return this; + } + {{#isListContainer}} + + public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) { + {{^required}} + if (this.{{name}} == null) { + this.{{name}} = {{{defaultValue}}}; + } + {{/required}} + this.{{name}}.add({{name}}Item); + return this; + } + {{/isListContainer}} + {{#isMapContainer}} + + public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) { + {{^required}} + if (this.{{name}} == null) { + this.{{name}} = {{{defaultValue}}}; + } + {{/required}} + this.{{name}}.put(key, {{name}}Item); + return this; + } + {{/isMapContainer}} + + {{/isReadOnly}} + /** + {{#description}} + * {{description}} + {{/description}} + {{^description}} + * Get {{name}} + {{/description}} + {{#minimum}} + * minimum: {{minimum}} + {{/minimum}} + {{#maximum}} + * maximum: {{maximum}} + {{/maximum}} + * @return {{name}} + **/ +{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} @ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}") +{{#vendorExtensions.extraAnnotation}} + {{{vendorExtensions.extraAnnotation}}} +{{/vendorExtensions.extraAnnotation}} + public {{{datatypeWithEnum}}} {{getter}}() { + return {{name}}; + } + {{^isReadOnly}} + + public void {{setter}}({{{datatypeWithEnum}}} {{name}}) { + this.{{name}} = {{name}}; + } + {{/isReadOnly}} + + {{/vars}} + +{{^supportJava6}} + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + }{{#hasVars}} + {{classname}} {{classVarName}} = ({{classname}}) o; + return {{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} && + {{/hasMore}}{{/vars}}{{#parent}} && + super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}} + return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};{{/hasVars}} + } + + @Override + public int hashCode() { + return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}); + } + +{{/supportJava6}} +{{#supportJava6}} + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + }{{#hasVars}} + {{classname}} {{classVarName}} = ({{classname}}) o; + return {{#vars}}ObjectUtils.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} && + {{/hasMore}}{{/vars}}{{#parent}} && + super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}} + return true;{{/hasVars}} + } + + @Override + public int hashCode() { + return ObjectUtils.hashCodeMulti({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}); + } + +{{/supportJava6}} + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class {{classname}} {\n"); + {{#parent}}sb.append(" ").append(toIndentedString(super.toString())).append("\n");{{/parent}} + {{#vars}}sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n"); + {{/vars}}sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + {{#parcelableModel}} + public void writeToParcel(Parcel out, int flags) { + {{#parent}} super.writeToParcel(out, flags); {{/parent}} {{#vars}} + out.writeValue({{name}}); + {{/vars}} + } + + public {{classname}}() { + super(); + } + + {{classname}}(Parcel in) { + {{#parent}} super(in); {{/parent}} + {{#vars}} + {{#isPrimitiveType}} + {{name}} = ({{{datatypeWithEnum}}})in.readValue(null); + {{/isPrimitiveType}} + {{^isPrimitiveType}} + {{name}} = ({{{datatypeWithEnum}}})in.readValue({{complexType}}.class.getClassLoader()); + {{/isPrimitiveType}} + {{/vars}} + } + + public int describeContents() { + return 0; + } + + public static final Parcelable.Creator<{{classname}}> CREATOR = new Parcelable.Creator<{{classname}}>() { + public {{classname}} createFromParcel(Parcel in) { + return new {{classname}}(in); + } + public {{classname}}[] newArray(int size) { + return new {{classname}}[size]; + } + }; + {{/parcelableModel}} +} diff --git a/generator/cybersource-java-template/pojo_doc.mustache b/generator/cybersource-java-template/pojo_doc.mustache new file mode 100644 index 000000000..0e4c07498 --- /dev/null +++ b/generator/cybersource-java-template/pojo_doc.mustache @@ -0,0 +1,15 @@ +# {{classname}} + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +{{#vars}}**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isPrimitiveType}}**{{datatype}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{datatype}}**]({{complexType}}.md){{/isPrimitiveType}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#readOnly}} [readonly]{{/readOnly}} +{{/vars}} +{{#vars}}{{#isEnum}} + + +## Enum: {{datatypeWithEnum}} +Name | Value +---- | -----{{#allowableValues}}{{#enumVars}} +{{name}} | {{value}}{{/enumVars}}{{/allowableValues}} +{{/isEnum}}{{/vars}} diff --git a/generator/cybersource-java-template/pom.mustache b/generator/cybersource-java-template/pom.mustache new file mode 100644 index 000000000..bcc0cc4b1 --- /dev/null +++ b/generator/cybersource-java-template/pom.mustache @@ -0,0 +1,319 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + {{artifactUrl}} + {{artifactDescription}} + + {{scmConnection}} + {{scmDeveloperConnection}} + {{scmUrl}} + + + 2.2.0 + + + + + {{licenseName}} + {{licenseUrl}} + repo + + + + + + {{developerName}} + {{developerEmail}} + {{developerOrganization}} + {{developerOrganizationUrl}} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + {{#java8}} + 1.8 + 1.8 + {{/java8}} + {{^java8}} + 1.7 + 1.7 + {{/java8}} + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-annotations-version} + + + + + com.sun.jersey + jersey-client + ${jersey-version} + + + com.sun.jersey.contribs + jersey-multipart + ${jersey-version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + ${jackson-version} + + {{#withXml}} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson-version} + + + {{/withXml}} + {{#java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-version} + + {{/java8}} + {{^java8}} + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson-version} + + + joda-time + joda-time + ${jodatime-version} + + + + + com.brsanthu + migbase64 + 2.2 + + {{/java8}} + + {{#supportJava6}} + + org.apache.commons + commons-lang3 + ${commons_lang3_version} + + + + commons-io + commons-io + ${commons_io_version} + + {{/supportJava6}} +{{#useBeanValidation}} + + + javax.validation + validation-api + 1.1.0.Final + provided + +{{/useBeanValidation}} + + {{#parcelableModel}} + + + com.google.android + android + 4.1.1.4 + provided + + {{/parcelableModel}} + + + + junit + junit + ${junit-version} + test + + + + UTF-8 + 1.5.15 + 1.19.4 + 2.8.9 + {{^java8}} + 2.9.9 + {{/java8}} + {{#supportJava6}} + 2.5 + 3.6 + {{/supportJava6}} + 1.0.0 + 4.12 + + diff --git a/generator/cybersource-java-template/settings.gradle.mustache b/generator/cybersource-java-template/settings.gradle.mustache new file mode 100644 index 000000000..b8fd6c4c4 --- /dev/null +++ b/generator/cybersource-java-template/settings.gradle.mustache @@ -0,0 +1 @@ +rootProject.name = "{{artifactId}}" \ No newline at end of file diff --git a/generator/cybersource-java-template/travis.mustache b/generator/cybersource-java-template/travis.mustache new file mode 100644 index 000000000..70cb81a67 --- /dev/null +++ b/generator/cybersource-java-template/travis.mustache @@ -0,0 +1,17 @@ +# +# Generated by: https://github.com/swagger-api/swagger-codegen.git +# +language: java +jdk: + - oraclejdk8 + - oraclejdk7 +before_install: + # ensure gradlew has proper permission + - chmod a+x ./gradlew +script: + # test using maven + - mvn test + # uncomment below to test using gradle + # - gradle test + # uncomment below to test using sbt + # - sbt test diff --git a/generator/cybersource-java-template/typeInfoAnnotation.mustache b/generator/cybersource-java-template/typeInfoAnnotation.mustache new file mode 100644 index 000000000..2d7983d01 --- /dev/null +++ b/generator/cybersource-java-template/typeInfoAnnotation.mustache @@ -0,0 +1,7 @@ +{{#jackson}} +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator}}", visible = true ) +@JsonSubTypes({ + {{#children}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"), + {{/children}} +}){{/jackson}} diff --git a/generator/cybersource-java-template/xmlAnnotation.mustache b/generator/cybersource-java-template/xmlAnnotation.mustache new file mode 100644 index 000000000..fd81a4cf5 --- /dev/null +++ b/generator/cybersource-java-template/xmlAnnotation.mustache @@ -0,0 +1,6 @@ +{{#withXml}} +{{#jackson}} +@JacksonXmlRootElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{classname}}{{/xmlName}}") +{{/jackson}} +@XmlRootElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{classname}}{{/xmlName}}") +@XmlAccessorType(XmlAccessType.FIELD){{/withXml}} \ No newline at end of file diff --git a/generator/cybersource-rest-spec.json b/generator/cybersource-rest-spec.json new file mode 100644 index 000000000..e470f0f6c --- /dev/null +++ b/generator/cybersource-rest-spec.json @@ -0,0 +1 @@ +{"swagger":"2.0","info":{"description":"Simple PAN tokenization service","version":"0.0.1","title":"CyberSource Flex API"},"host":"apitest.cybersource.com","schemes":["https"],"basePath":"/","consumes":["application/json;charset=utf-8"],"produces":["application/json;charset=utf-8"],"tags":[{"name":"Flex API"}],"paths":{"/flex/v1/keys/":{"x-name":"Generate Key","x-description":"Generate a one-time use public key and key ID to encrypt the card number in the follow-on Tokenize Card request. The key used to encrypt the card number on the cardholder\u2019s device or browser is valid for 15 minutes and must be used to verify the signature in the response message. CyberSource recommends creating a new key for each order. Generating a key is an authenticated request initiated from your servers, prior to requesting to tokenize the card data from your customer\u2019s device or browser.","post":{"tags":["KeyGeneration"],"summary":"Generate Key","description":"Generate a one-time use public key and key ID to encrypt the card number in the follow-on Tokenize Card request. The key used to encrypt the card number on the cardholder\u2019s device or browser is valid for 15 minutes and must be used to verify the signature in the response message. CyberSource recommends creating a new key for each order. Generating a key is an authenticated request initiated from your servers, prior to requesting to tokenize the card data from your customer\u2019s device or browser.","operationId":"generatePublicKey","produces":["application/json"],"parameters":[{"in":"body","name":"generatePublicKeyRequest","schema":{"required":["encryptionType"],"type":"object","properties":{"encryptionType":{"type":"string","description":"How the card number should be encrypted in the subsequent Tokenize Card request. Possible values are RsaOaep256 or None (if using this value the card number must be in plain text when included in the Tokenize Card request). The Tokenize Card request uses a secure connection (TLS 1.2+) regardless of what encryption type is specified."},"targetOrigin":{"type":"string","description":"This should only be used if using the Microform implementation. This is the protocol, URL, and if used, port number of the page that will host the Microform. Unless using http://localhost, the protocol must be https://. For example, if serving Microform on example.com, the targetOrigin is https://example.com The value is used to restrict the frame ancestor of the Microform. If there is a mismatch between this value and the frame ancestor, the Microfrom will not load."},"unmaskedLeft":{"type":"integer","description":"Specifies the number of card number digits to be returned un-masked from the left. For example, setting this value to 6 will return: 411111XXXXXXXXXX Default value: 6 Maximum value: 6"},"unmaskedRight":{"type":"integer","description":"Specifies the number of card number digits to be returned un-masked from the right. For example, setting this value to 4 will return: 411111XXXXXX1111 Default value: 4 Maximum value: 4"},"enableBillingAddress":{"type":"boolean","description":"Specifies whether or not 'dummy' address data should be specified in the create token request. If you have 'Relaxed AVS' enabled for your MID, this value can be set to False.Default value: true"},"currency":{"type":"string","description":"Three character ISO currency code to be associated with the token. Required for legacy integrations. Default value: USD."},"enableAutoAuth":{"type":"boolean","description":"Specifies whether or not an account verification authorization ($0 Authorization) is carried out on token creation. Default is false, as it is assumed a full or zero amount authorization will be carried out in a separate call from your server."}}}}],"x-example":{"example0":{"summary":"Generate Key","value":{"encryptionType":"RsaOaep256"}}},"responses":{"200":{"description":"Retrieved key.","schema":{"title":"flexV1KeysPost200Response","properties":{"keyId":{"type":"string","description":"Unique identifier for the generated token. Used in the subsequent Tokenize Card request from your customer\u2019s device or browser."},"der":{"type":"object","description":"The public key in DER format. Used to validate the response from the Tokenize Card request. Additionally this format is useful for client side encryption in Android and iOS implementations.","properties":{"format":{"type":"string","description":"Specifies the format of the public key; currently X.509."},"algorithm":{"type":"string","description":"Algorithm used to encrypt the public key."},"publicKey":{"type":"string","description":"Base64 encoded public key value."}}},"jwk":{"type":"object","description":"The public key in JSON Web Key (JWK) format. This format is useful for client side encryption in JavaScript based implementations.","properties":{"kty":{"type":"string","description":"Algorithm used to encrypt the public key."},"use":{"type":"string","description":"Defines whether to use the key for encryption (enc) or verifying a signature (sig). Always returned as enc."},"kid":{"type":"string","description":"The key ID in JWK format."},"n":{"type":"string","description":"JWK RSA Modulus"},"e":{"type":"string","description":"JWK RSA Exponent"}}}}}},"default":{"description":"Error retrieving key.","schema":{"type":"object","properties":{"responseStatus":{"properties":{"status":{"type":"number","description":"HTTP Status code."},"reason":{"type":"string","description":"Error Reason Code."},"message":{"type":"string","description":"Error Message."},"correlationId":{"type":"string","description":"API correlation ID."},"details":{"type":"array","items":{"properties":{"location":{"type":"string","description":"Field name referred to for validation issues."},"message":{"type":"string","description":"Description or code of any error response."}}}}}},"_links":{"type":"object","properties":{"next":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"documentation":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"self":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}}}}}}},"x-samplePayload":{"encryptionType":"RsaOaep256"},"x-sampleResponse":{"keyId":"05BgbFie7vX5vzSMKOoqEAAdfpdR4kas","der":{"format":"X.509","algorithm":"RSA","publicKey":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgC1G6rVue4w/jjJrKPZusGN9G+Y7mWuLJ0O2/GHd94LvR51+ok7ahuQUVMZLdigixnspaGo/WVLvTTZ5J28Cc1uSx0o/BsxpNaAQD8/aBZL3nnAiBLACxI1JHAVo7SXbJQmz+mqVFYTppg9QmpB2ATTmXjUOQy+Fqkw3EByfCANHhHSNs4+HASovsfcRMUmmvDfTd5qBb23KzDJeDVqTYWa3XjUorlZOCJuLyPgeDEK8oOC9C4W9dn32z8FJ4E6Dz28M/2O3g8FLQD2F+NezkQJsl8MEYo4rl1nr7/oIkMsYLCCoG8jwmryErb7km9JWWgqZ80trkjijFqDAbHfUEwIDAQAB"},"jwk":{"kty":"RSA","use":"enc","kid":"05BgbFie7vX5vzSMKOoqEAAdfpdR4kas","n":"fC1G6rVue4w_jjJrKPZusGN9G-Y7mWuLJ0O2_GHd94LvR51-ok7ahuQUVMZLdigixnspaGo_WVLvTTZ5J28Cc1uSx0o_BsxpNaAQD8_aBZL3nnAiBLACxI1JHAVo7SXAJQmz-mqVFYTppg9QmpB2ATTmXjUOQy-Fqkw3EByfCANHhHSNs4-HASovsfcRMUmmvDfTd5qBb23KzDJeDVqTYWa3XjUorlZOCJuLyPgeDEK8oOC9C4W9dn32z8FJ4E6Dz28M_2O3g8FLQD2F-NezkQJsl8MEYo4rl1nr7_oIkMsYLCCoG8jwmryErb7km9JWWgqZ80trkjijFqDAbHfUEw","e":"AQAB"}}}},"/flex/v1/tokens/":{"x-name":"Flex Tokenize Card","x-description":"Returns a token representing the supplied card details. The token replaces card data and can be used as the Subscription ID in the CyberSource Simple Order API or SCMP API. This is an unauthenticated call that you should initiate from your customer\u2019s device or browser.","post":{"tags":["FlexToken"],"summary":"Flex Tokenize card","description":"Returns a token representing the supplied card details. The token replaces card data and can be used as the Subscription ID in the CyberSource Simple Order API or SCMP API. This is an unauthenticated call that you should initiate from your customer\u2019s device or browser.","operationId":"tokenize","produces":["application/json"],"parameters":[{"in":"body","name":"tokenizeRequest","schema":{"type":"object","properties":{"keyId":{"type":"string","description":"Unique identifier for the generated token. This is obtained from the Generate Key request. See the [Java Script and Java examples] (http://apps.cybersource.com/library/documentation/dev_guides/Secure_Acceptance_Flex/Key/html) on how to import the key and encrypt using the imported key."},"cardInfo":{"type":"object","properties":{"cardNumber":{"type":"string","description":"Encrypted or plain text card number. If the encryption type of \u201cNone\u201d was used in the Generate Key request, this value can be set to the plaintext card number/Personal Account Number (PAN). If the encryption type of RsaOaep256 was used in the Generate Key request, this value needs to be the RSA OAEP 256 encrypted card number. The card number should be encrypted on the cardholders\u2019 device. The [WebCrypto API] (https://github.com/CyberSource/cybersource-flex-samples/blob/master/java/spring-boot/src/main/resources/public/flex.js) can be used with the JWK obtained in the Generate Key request."},"cardExpirationMonth":{"type":"string","description":"Two digit expiration month"},"cardExpirationYear":{"type":"string","description":"Four digit expiration year"},"cardType":{"type":"string","description":"Card Type. This field is required. Refer to the CyberSource Credit Card Services documentation for supported card types."}}}}}}],"x-example":{"example0":{"summary":"Flex Tokenize Card","value":{"keyId":"05BgbFie7vX5vzSMKOoqEAAdfpdR4kas","cardInfo":{"cardNumber":"4111111111111111","cardExpirationMonth":"12","cardExpirationYear":"2031","cardType":"001"}}}},"responses":{"200":{"description":"Created payment token.","schema":{"title":"flexV1TokensPost200Response","properties":{"keyId":{"type":"string","description":"The Key ID."},"token":{"type":"string","description":"The generated token. The token replaces card data and is used as the Subscription ID in the CyberSource Simple Order API or SCMP API."},"maskedPan":{"type":"string","description":"The masked card number displaying the first 6 digits and the last 4 digits."},"cardType":{"type":"string","description":"The card type."},"timestamp":{"type":"integer","format":"int64","description":"The UTC date and time in milliseconds at which the signature was generated."},"signedFields":{"type":"string","description":"Indicates which fields from the response make up the data that is used when verifying the response signature. See the [sample code] (https://github.com/CyberSource/cybersource-flex-samples/blob/master/java/spring-boot/src/main/java/com/cybersource/flex/application/CheckoutController.java) on how to verify the signature."},"signature":{"type":"string","description":"Flex-generated digital signature. To ensure the values have not been tampered with while passing through the client, verify this server-side using the public key generated from the /keys resource."},"discoverableServices":{"type":"object","additionalProperties":{"type":"object"}}}}},"default":{"description":"Error creating token.","schema":{"type":"object","properties":{"responseStatus":{"properties":{"status":{"type":"number","description":"HTTP Status code."},"reason":{"type":"string","description":"Error Reason Code."},"message":{"type":"string","description":"Error Message."},"correlationId":{"type":"string","description":"API correlation ID."},"details":{"type":"array","items":{"properties":{"location":{"type":"string","description":"Field name referred to for validation issues."},"message":{"type":"string","description":"Description or code of any error response."}}}}}},"_links":{"type":"object","properties":{"next":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"documentation":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"self":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}}}}}}},"x-samplePayload":{"keyId":"05BgbFie7vX5vzSMKOoqEAAdfpdR4kas","cardDetails":{"cardNumber":"ejbhIpMEgYnIODcB4//rrVxMHrqHcnLD6pDRF36jlEk72bETAfiOoxmpI9pGiidqMmkgAnvJfVgR3CLAV5EdG4Mu5IWK26QRnVtwvsVEUtpah7IylbxV9MLvXh2FjIJskKCWNLidb1G4PN5963hnV3IoZd2pF99JwV9lPhOHT5ymlNeg7sTzQQDN1I0/yJApds+t79hl9QVp4PusUDfSsPQTtR2frzlH4V3W+XjHDhmy5oNhiUaVxv27cyG1SWeCKkVC9tc8zLy4pvlgoplrLV8JRaS9hfWalJjv2xtk3DXmNT2urtFv2evcI3LM/S29KlJjPXZcBp0IYyB/taunCA==","cardType":"001"}},"x-sampleResponse":{"keyId":"05BgbFie7vX5vzSMKOoqEAAdfpdR4kas","token":"0100153497304242","maskedPan":"424242XXXXXX4242","cardType":"001","timestamp":1472733222651,"signedFields":"token,cardType,maskedPan,timestamp","signature":"TcM7METFOIidwbxWG2Xhawx/5gZ7hZB0Lyrhg3NRJ+Pma+Nq7BugvsqLCE2R24+h13xnM6vpJXR2cqfQPkxhb6joJT8jcciEf+lj6h/KjvXuR4pJ4fMll4WS1Z4+574ps0ysV/5zs7kT2IAZj7i+szlYwFJxGhOGC0218x1N0NxELTDyU/HI6n+Aa+mYBqkMXth42t+GNQ7goVXkJWRgQSjp2v0WTh2d2plDnxEWPURZXz7GLdQXRIYUWWx/L5JSf88F1zgjYDpBitNSYBMMILKfDd3KEg+6nIruCln5kDMbTRD8LwPpGYC9tyM9+UM8MBINPHhaqdFp2wHF7dccKA==","discoverableServices":[]}}},"/pts/v2/payments/":{"post":{"summary":"Process a Payment","description":"Authorize the payment for the transaction.\n","tags":["payments"],"operationId":"createPayment","parameters":[{"name":"createPaymentRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"transactionId":{"type":"string","description":"Identifier that you assign to the transaction. See \"Merchant-Initiated Reversals and Voids,\" page 176\n"},"comments":{"type":"string","description":"Comments"}}},"processingInformation":{"type":"object","properties":{"capture":{"type":"boolean","description":"Flag that specifies whether to also include capture service in the submitted request or not.","enum":[true,false],"default":false},"processorId":{"type":"string","maxLength":3,"description":"Value that identifies the processor/acquirer to use for the transaction. This value is supported only for\n**CyberSource through VisaNet**.\n"},"businessApplicationId":{"type":"string","description":"Description of this field is not available."},"commerceIndicator":{"type":"string","maxLength":20,"description":"Type of transaction. Some payment card companies use this information when determining discount rates. When you\nomit this field for **Ingenico ePayments**, the processor uses the default transaction type they have on file\nfor you instead of the default value listed here.\n"},"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"reconciliationId":{"type":"string","maxLength":60,"description":"Please check with Cybersource customer support to see if your merchant account is configured correctly so you\ncan include this field in your request.\n* For Payouts: max length for FDCCompass is String (22).\n"},"linkId":{"type":"string","maxLength":26,"description":"Value that links the current payment request to the original request. Set this value\nto the ID that was returned in the reply message from the original payment request.\n\nThis value is used for:\n\n - Partial authorizations.\n - Split shipments.\n"},"purchaseLevel":{"type":"string","maxLength":1,"description":"Set this field to 3 to indicate that the request includes Level III data."},"reportGroup":{"type":"string","maxLength":25,"description":"Attribute that lets you define custom grouping for your processor reports. This field is supported only for\n**Litle**.\n"},"visaCheckoutId":{"type":"string","maxLength":48,"description":"Identifier for the **Visa Checkout** order. Visa Checkout provides a unique order ID for every transaction in\nthe Visa Checkout **callID** field.\n"},"issuer":{"type":"object","properties":{"discretionaryData":{"type":"string","maxLength":255,"description":"Data defined by the issuer. The value for this reply field will probably be the same as the value that you\nsubmitted in the authorization request, but it is possible for the processor, issuer, or acquirer to modify\nthe value.\n\nThis field is supported only for Visa transactions on **CyberSource through VisaNet**.\n"}}},"authorizationOptions":{"type":"object","properties":{"authType":{"type":"string","maxLength":15,"description":"Authorization type. Possible values:\n\n - **AUTOCAPTURE**: automatic capture.\n - **STANDARDCAPTURE**: standard capture.\n - **VERBAL**: forced capture. Include it in the payment request for a forced capture. Include it in the capture\n request for a verbal payment.\n\nFor processor-specific information, see the auth_type field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"verbalAuthCode":{"type":"string","maxLength":7,"description":"Authorization code.\n\n**Forced Capture**\n\nUse this field to send the authorization code you received from a payment that you authorized\noutside the CyberSource system.\n\n**Verbal Authorization**\n\nUse this field in CAPTURE API to send the verbally received authorization code.\n\nFor processor-specific information, see the auth_code field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"verbalAuthTransactionId":{"type":"string","maxLength":15,"description":"Transaction ID (TID)."},"authIndicator":{"type":"string","maxLength":1,"description":"Flag that specifies the purpose of the authorization.\n\nPossible values:\n - **0**: Preauthorization\n - **1**: Final authorization\n\nFor processor-specific information, see the auth_indicator field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"partialAuthIndicator":{"type":"boolean","description":"Flag that indicates whether the transaction is enabled for partial authorization or not. When your request\nincludes this field, this value overrides the information in your CyberSource account. For processor-specific\ninformation, see the auth_partial_auth_indicator field in [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n","enum":[true,false]},"balanceInquiry":{"type":"boolean","description":"Flag that indicates whether to return balance information.","enum":[true,false]},"ignoreAvsResult":{"type":"boolean","description":"Flag that indicates whether to allow the capture service to run even when the payment\nreceives an AVS decline.\n","enum":[true,false],"default":false},"declineAvsFlags":{"type":"array","description":"An array of AVS flags that cause the reply flag to be returned.\n\n`Important` To receive declines for the AVS code N, include the value N in the array.\n","items":{"type":"string","enum":["D","A","V","S","N","O"]}},"ignoreCvResult":{"type":"boolean","description":"Flag that indicates whether to allow the capture service to run even when\nthe payment receives a CVN decline.\n","enum":[true,false],"default":false},"initiator":{"type":"object","properties":{"type":{"type":"string","description":"This field indicates whether the transaction is a merchant-initiated transaction or customer-initiated transaction.\n","enum":["customer","merchant"]},"credentialStoredOnFile":{"type":"boolean","description":"Flag that indicates whether merchant is intend to use this transaction to store payment credential for follow-up\nmerchant-initiated transactions or not.\n","enum":[true,false]},"storedCredentialUsed":{"type":"boolean","description":"Flag that indicates whether merchant is intend to use this transaction to store payment credential for follow-up\nmerchant-initiated transactions or not.\n","enum":[true,false]},"merchantInitiatedTransaction":{"type":"object","properties":{"reason":{"type":"string","maxLength":1,"description":"Reason for the merchant-initiated transaction. Possible values:\n\n - **1**: Resubmission\n - **2**: Delayed charge\n - **3**: Reauthorization for split shipment\n - **4**: No show\n - **5**: Account top up\n\nThis field is not required for installment payments or recurring payments or when _reAuth.first_ is true. It is\nrequired for all other merchant-initiated transactions. This field is supported only for Visa transactions on CyberSource through\nVisaNet.\n"},"previousTransactionId":{"type":"string","maxLength":15,"description":"Transaction identifier that was returned in the payment response field _processorInformation.transactionID_\nin the reply message for either the original merchant initiated payment in the series or the previous\nmerchant-initiated payment in the series.

If the current payment request includes a token\ninstead of an account number, the following time limits apply for the value of this field:\n\nFor a **resubmission**, the transaction ID must be less than 14 days old.\n\nFor a **delayed charge** or **reauthorization**, the transaction ID must be less than 30 days old.\n\nThe value for this field does not correspond to any data in the TC 33 capture file. This field is supported\nonly for Visa transactions on CyberSource through VisaNet.\n"}}}}}}},"captureOptions":{"type":"object","properties":{"captureSequenceNumber":{"type":"number","minimum":1,"maximum":99,"description":"Capture number when requesting multiple partial captures for one payment.\nUsed along with _totalCaptureCount_ to track which capture is being processed.\n\nFor example, the second of five captures would be passed to CyberSource as:\n - _captureSequenceNumber_ = 2, and\n - _totalCaptureCount_ = 5\n"},"totalCaptureCount":{"type":"number","minimum":1,"maximum":99,"description":"Total number of captures when requesting multiple partial captures for one payment.\nUsed along with _captureSequenceNumber_ which capture is being processed.\n\nFor example, the second of five captures would be passed to CyberSource as:\n - _captureSequenceNumber_ = 2, and\n - _totalCaptureCount_ = 5\n"},"dateToCapture":{"type":"string","maxLength":4,"description":"Date on which you want the capture to occur. This field is supported only for **CyberSource through VisaNet**.\n`Format: MMDD`\n"}}},"recurringOptions":{"type":"object","properties":{"loanPayment":{"type":"boolean","description":"Flag that indicates whether this is a payment towards an existing contractual loan.\n","enum":[true,false],"default":false},"firstRecurringPayment":{"type":"boolean","description":"Flag that indicates whether this transaction is the first in a series of recurring payments. This field is\nsupported only for **Atos**, **FDC Nashville Global**, and **OmniPay Direct**.\n","enum":[true,false],"default":false}}}}},"paymentInformation":{"type":"object","properties":{"card":{"type":"object","properties":{"number":{"type":"string","maxLength":20,"description":"Customer\u2019s credit card number. Encoded Account Numbers when processing encoded account numbers, use this field\nfor the encoded account number.\n\nFor processor-specific information, see the customer_cc_number field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationMonth":{"type":"string","maxLength":2,"description":"Two-digit month in which the credit card expires. `Format: MM`. Possible values: 01 through 12.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 12.\n\nFor processor-specific information, see the customer_cc_expmo field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationYear":{"type":"string","maxLength":4,"description":"Four-digit year in which the credit card expires. `Format: YYYY`.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 2021.\n\nFor processor-specific information, see the customer_cc_expyr field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"},"useAs":{"type":"string","maxLength":2,"description":"Flag that specifies the type of account associated with the card. The cardholder provides this information\nduring the payment process.\n\n**Cielo** and **Comercio Latino**\n\nPossible values:\n\n - CREDIT: Credit card\n - DEBIT: Debit card\n\nThis field is required for:\n - Debit transactions on Cielo and Comercio Latino.\n - Transactions with Brazilian-issued cards on CyberSource through VisaNet.\n"},"sourceAccountType":{"type":"string","maxLength":2,"description":"Flag that specifies the type of account associated with the card. The cardholder provides this information\nduring the payment process. This field is required in the following cases.\n - Debit transactions on Cielo and Comercio Latino.\n - Transactions with Brazilian-issued cards on CyberSource through VisaNet.\n - Applicable only for CTV.\n \n**Note**\nCombo cards in Brazil contain credit and debit functionality in a single card. Visa systems use a credit bank\nidentification number (BIN) for this type of card. Using the BIN to determine whether a card is debit or\ncredit can cause transactions with these cards to be processed incorrectly. CyberSource strongly recommends\nthat you include this field for combo card transactions.\n\nPossible values include the following.\n\n - CHECKING: Checking account\n - CREDIT: Credit card account\n - SAVING: Saving account\n - LINE_OF_CREDIT: Line of credit\n - PREPAID: Prepaid card account\n - UNIVERSAL: Universal account\n"},"securityCode":{"type":"string","maxLength":4,"description":"Card Verification Number."},"securityCodeIndicator":{"type":"string","maxLength":1,"description":"Flag that indicates whether a CVN code was sent. Possible values:\n\n - 0 (default): CVN service not requested. CyberSource uses this default value when you do not include\n _securityCode_ in the request.\n - 1 (default): CVN service requested and supported. CyberSource uses this default value when you include\n _securityCode_ in the request.\n - 2: CVN on credit card is illegible.\n - 9: CVN was not imprinted on credit card.\n"},"accountEncoderId":{"type":"string","maxLength":3,"description":"Identifier for the issuing bank that provided the customer\u2019s encoded account number. Contact your processor\nfor the bank\u2019s ID.\n"},"issueNumber":{"type":"string","maxLength":5,"description":"Number of times a Maestro (UK Domestic) card has been issued to the account holder. The card might or might\nnot have an issue number. The number can consist of one or two digits, and the first digit might be a zero.\nWhen you include this value in your request, include exactly what is printed on the card. A value of 2 is\ndifferent than a value of 02. Do not include the field, even with a blank value, if the card is not a\nMaestro (UK Domestic) card.\n\nThe issue number is not required for Maestro (UK Domestic) transactions.\n"},"startMonth":{"type":"string","maxLength":2,"description":"Month of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: MM`. Possible values: 01 through 12.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"},"startYear":{"type":"string","maxLength":4,"description":"Year of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: YYYY`.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"}}},"tokenizedCard":{"type":"object","properties":{"number":{"type":"string","maxLength":20,"description":"Customer\u2019s payment network token value.\n"},"expirationMonth":{"type":"string","maxLength":2,"description":"Two-digit month in which the payment network token expires. `Format: MM`. Possible values: 01 through 12.\n"},"expirationYear":{"type":"string","maxLength":4,"description":"Four-digit year in which the payment network token expires. `Format: YYYY`.\n"},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"},"cryptogram":{"type":"string","maxLength":40,"description":"This field is used internally."},"requestorId":{"type":"string","maxLength":11,"description":"Value that identifies your business and indicates that the cardholder\u2019s account number is tokenized. This value\nis assigned by the token service provider and is unique within the token service provider\u2019s database.\n\n`Note` This field is supported only for **CyberSource through VisaNet** and **FDC Nashville Global**.\n"},"transactionType":{"type":"string","maxLength":1,"description":"Type of transaction that provided the token data. This value does not specify the token service provider; it\nspecifies the entity that provided you with information about the token.\n\nSet the value for this field to 1. An application on the customer\u2019s mobile device provided the token data.\n"},"assuranceLevel":{"type":"string","maxLength":2,"description":"Confidence level of the tokenization. This value is assigned by the token service provider.\n\n`Note` This field is supported only for **CyberSource through VisaNet** and **FDC Nashville Global**.\n"},"storageMethod":{"type":"string","maxLength":3,"description":"Type of technology used in the device to store token data. Possible values:\n\n - 001: Secure Element (SE)\n\nSmart card or memory with restricted access and encryption to prevent data tampering. For storing payment\ncredentials, a SE is tested against a set of requirements defined by the payment networks.\n\n`Note` This field is supported only for **FDC Compass**.\n\n- 002: Host Card Emulation (HCE)\n\nEmulation of a smart card by using software to create a virtual and exact representation of the card.\nSensitive data is stored in a database that is hosted in the cloud. For storing payment credentials, a database\nmust meet very stringent security requirements that exceed PCI DSS.\n\n`Note` This field is supported only for **FDC Compass**.\n"},"securityCode":{"type":"string","maxLength":4,"description":"CVN."}}},"fluidData":{"type":"object","properties":{"key":{"type":"string","description":"Description of this field is not available."},"descriptor":{"type":"string","maxLength":128,"description":"Format of the encrypted payment data."},"value":{"type":"string","maxLength":3072,"description":"The encrypted payment data value. If using Apple Pay or Samsung Pay, the values are:\n - Apple Pay: RklEPUNPTU1PTi5BUFBMRS5JTkFQUC5QQVlNRU5U\n - Samsung Pay: RklEPUNPTU1PTi5TQU1TVU5HLklOQVBQLlBBWU1FTlQ=\n"},"encoding":{"type":"string","maxLength":6,"description":"Encoding method used to encrypt the payment data.\n\nPossible value: Base64\n"}}},"customer":{"type":"object","properties":{"customerId":{"type":"string","maxLength":26,"description":"Unique identifier for the customer's card and billing information."}}}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"},"discountAmount":{"type":"string","maxLength":15,"description":"Total discount amount applied to the order.\n\nFor processor-specific information, see the order_discount_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"dutyAmount":{"type":"string","maxLength":15,"description":"Total charges for any import or export duties included in the order.\n\nFor processor-specific information, see the duty_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAmount":{"type":"string","maxLength":12,"description":"Total tax amount for all the items in the order.\n\nFor processor-specific information, see the total_tax_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"nationalTaxIncluded":{"type":"string","maxLength":1,"description":"Flag that indicates whether a national tax is included in the order total.\n\nPossible values:\n\n - **0**: national tax not included\n - **1**: national tax included\n\nFor processor-specific information, see the national_tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag that indicates how the merchant manages discounts.\n\nPossible values:\n\n - **0**: no invoice level discount included\n - **1**: tax calculated on the postdiscount invoice total\n - **2**: tax calculated on the prediscount invoice total\n\nFor processor-specific information, see the order_discount_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedLevel":{"type":"string","maxLength":1,"description":"Flag that indicates how you calculate tax.\n\nPossible values:\n\n - **0**: net prices with tax calculated at line item level\n - **1**: net prices with tax calculated at invoice level\n - **2**: gross prices with tax provided at line item level\n - **3**: gross prices with tax provided at invoice level\n - **4**: no tax applies on the invoice for the transaction\n\nFor processor-specific information, see the tax_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxTypeCode":{"type":"string","maxLength":3,"description":"For tax amounts that can be categorized as one tax type.\n\nThis field contains the tax type code that corresponds to the entry in the _lineItems.taxAmount_ field.\n\nPossible values:\n\n - **056**: sales tax (U.S only)\n - **TX~**: all taxes (Canada only) Note ~ = space.\n\nFor processor-specific information, see the total_tax_type_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"freightAmount":{"type":"string","maxLength":13,"description":"Total freight or shipping and handling charges for the order. When you include this field in your request, you\nmust also include the **totalAmount** field.\n\nFor processor-specific information, see the freight_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"foreignAmount":{"type":"string","maxLength":15,"description":"Converted amount returned by the DCC service.\n\nFor processor-specific information, see the foreign_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"foreignCurrency":{"type":"string","maxLength":5,"description":"Billing currency returned by the DCC service.\n\nFor processor-specific information, see the foreign_currency field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRate":{"type":"string","maxLength":13,"description":"Exchange rate returned by the DCC service. Includes a decimal point and a maximum of 4 decimal places.\n\nFor processor-specific information, see the exchange_rate field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRateTimeStamp":{"type":"string","maxLength":14,"description":"Time stamp for the exchange rate. This value is returned by the DCC service.\n\nFormat: `YYYYMMDD~HH:MM` where ~ denotes a space.\n\nFor processor-specific information, see the exchange_rate_timestamp field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"surcharge":{"type":"object","properties":{"amount":{"type":"string","maxLength":15,"description":"The surcharge amount is included in the total transaction amount but is passed in a separate field to the issuer\nand acquirer for tracking. The issuer can provide information about the surcharge amount to the customer.\n\n- Applicable only for CTV for Payouts.\n- CTV (<= 08)\n\nFor processor-specific information, see the surcharge_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"description":{"type":"string","description":"Description of this field is not available."}}},"settlementAmount":{"type":"string","maxLength":12,"description":"This is a multicurrency field. It contains the transaction amount (field 4), converted to the Currency used to bill the cardholder\u2019s account.\n"},"settlementCurrency":{"type":"string","maxLength":3,"description":"This is a multicurrency-only field. It contains a 3-digit numeric code that identifies the currency used by the issuer to bill the cardholder's account.\n"},"amexAdditionalAmounts":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","maxLength":3,"description":"Additional amount type. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount_type field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amount":{"type":"string","maxLength":12,"description":"Additional amount. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}}},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"middleName":{"type":"string","maxLength":60,"description":"Customer\u2019s middle name.\n"},"nameSuffix":{"type":"string","maxLength":60,"description":"Customer\u2019s name suffix.\n"},"title":{"type":"string","maxLength":60,"description":"Title.\n"},"company":{"type":"string","maxLength":60,"description":"Name of the customer\u2019s company.\n\nFor processor-specific information, see the company_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the billing street address as it appears on the credit card issuer\u2019s records.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address1 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address2":{"type":"string","maxLength":60,"description":"Additional address information.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address2 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":50,"description":"City of the billing address.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_city field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the billing address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_state field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the billing address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_zip field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"district":{"type":"string","maxLength":50,"description":"Customer\u2019s neighborhood, community, or region (a barrio in Brazil) within the city or municipality. This\nfield is available only on **Cielo**.\n"},"buildingNumber":{"type":"string","maxLength":256,"description":"Building number in the street address.\n\nThis field is supported only for:\n - Cielo transactions.\n - Redecard customer validation with CyberSource Latin American Processing.\n"},"email":{"type":"string","maxLength":255,"description":"Customer's email address, including the full domain name.\n\nFor processor-specific information, see the customer_email field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneType":{"type":"string","enum":["day","home","night","work"],"description":"Customer's phone number type.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nPossible Values - \n* day\n* home\n* night\n* work\n"}}},"shipTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"First name of the recipient.\n\n**Processor specific maximum length**\n\n- Litle: 25\n- All other processors: 60\n"},"lastName":{"type":"string","maxLength":60,"description":"Last name of the recipient.\n\n**Processor specific maximum length**\n\n- Litle: 25\n- All other processors: 60\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the shipping address."},"address2":{"type":"string","maxLength":60,"description":"Second line of the shipping address."},"locality":{"type":"string","maxLength":50,"description":"City of the shipping address."},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the shipping address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the shipping address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n"},"country":{"type":"string","maxLength":2,"description":"Country of the shipping address. Use the two character ISO Standard Country Codes."},"district":{"type":"string","maxLength":50,"description":"Neighborhood, community, or region within a city or municipality."},"buildingNumber":{"type":"string","maxLength":15,"description":"Building number in the street address. For example, the building number is 187 in the following address:\n\nRua da Quitanda 187\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Phone number for the shipping address."},"company":{"type":"string","maxLength":60,"description":"Name of the customer\u2019s company.\n\nFor processor-specific information, see the company_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"lineItems":{"type":"array","items":{"type":"object","properties":{"productCode":{"type":"string","maxLength":255,"description":"Type of product. This value is used to determine the category that the product is in: electronic, handling,\nphysical, service, or shipping. The default value is **default**.\n\nFor a payment, when you set this field to a value other than default or any of the values related to\nshipping and handling, below fields _quantity_, _productName_, and _productSKU_ are required.\n"},"productName":{"type":"string","maxLength":255,"description":"For PAYMENT and CAPTURE API, this field is required when above _productCode_ is not **default** or one of the\nvalues related to shipping and handling.\n"},"productSku":{"type":"string","maxLength":255,"description":"Identification code for the product. For PAYMENT and CAPTURE API, this field is required when above\n_productCode_ is not **default** or one of the values related to shipping and/or handling.\n"},"quantity":{"type":"number","minimum":1,"maximum":9999999999,"description":"For a payment or capture, this field is required when _productCode_ is not **default** or one of the values\nrelated to shipping and handling.\n","default":1},"unitPrice":{"type":"string","maxLength":15,"description":"Per-item price of the product. This value cannot be negative. You can include a decimal point (.), but you\ncannot include any other special characters. CyberSource truncates the amount to the correct number of decimal\nplaces.\n\nFor processor-specific information, see the amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"unitOfMeasure":{"type":"string","maxLength":12,"description":"Unit of measure, or unit of measure code, for the item.\n"},"totalAmount":{"type":"string","maxLength":13,"description":"Total amount for the item. Normally calculated as the unit price x quantity.\n"},"taxAmount":{"type":"string","maxLength":15,"description":"Total tax to apply to the product. This value cannot be negative. The tax amount and the offer amount must\nbe in the same currency. The tax amount field is additive.\n\nThe following example uses a two-exponent currency such as USD:\n\n 1. You include each line item in your request.\n ..- 1st line item has amount=10.00, quantity=1, and taxAmount=0.80\n ..- 2nd line item has amount=20.00, quantity=1, and taxAmount=1.60\n 2. The total amount authorized will be 32.40, not 30.00 with 2.40 of tax included.\n\nThis field is frequently used for Level II and Level III transactions.\n"},"taxRate":{"type":"string","maxLength":7,"description":"Tax rate applied to the item. See \"Numbered Elements,\" page 14.\n\nVisa: Valid range is 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated).\n\nMastercard: Valid range is 0.00001 to 0.99999 (0.001% to 99.999%).\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag to indicate how you handle discount at the line item level.\n\n - 0: no line level discount provided\n - 1: tax was calculated on the post-discount line item total\n - 2: tax was calculated on the pre-discount line item total\n\n`Note` Visa will inset 0 (zero) if an invalid value is included in this field.\n\nThis field relates to the value in the _lineItems[].discountAmount_ field.\n"},"taxStatusIndicator":{"type":"string","maxLength":1,"description":"Flag to indicate whether tax is exempted or not included.\n\n - 0: tax not included\n - 1: tax included\n - 2: transaction is not subject to tax\n"},"taxTypeCode":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"amountIncludesTax":{"type":"boolean","description":"Flag that indicates whether the tax amount is included in the Line Item Total.\n","enum":[true,false]},"typeOfSupply":{"type":"string","maxLength":2,"description":"Flag to indicate whether the purchase is categorized as goods or services.\nPossible values:\n\n - 00: goods\n - 01: services\n"},"commodityCode":{"type":"string","maxLength":15,"description":"Commodity code or International description code used to classify the item. Contact your acquirer for a list of\ncodes.\n"},"discountAmount":{"type":"string","maxLength":13,"description":"Discount applied to the item."},"discountApplied":{"type":"boolean","description":"Flag that indicates whether the amount is discounted.\n\nIf you do not provide a value but you set Discount Amount to a value greater than zero, then CyberSource sets\nthis field to **true**.\n","enum":[true,false]},"discountRate":{"type":"string","maxLength":6,"description":"Rate the item is discounted. Maximum of 2 decimal places.\n\nExample 5.25 (=5.25%)\n"},"invoiceNumber":{"type":"string","maxLength":23,"description":"Field to support an invoice number for a transaction. You must specify the number of line items that will\ninclude an invoice number. By default, the first line item will include an invoice number field. The invoice\nnumber field can be included for up to 10 line items.\n"},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}},"fulfillmentType":{"type":"string","description":"TODO"}}}},"invoiceDetails":{"type":"object","properties":{"invoiceNumber":{"type":"string","description":"Invoice Number."},"barcodeNumber":{"type":"string","description":"Barcode Number."},"expirationDate":{"type":"string","description":"Expiration Date."},"purchaseOrderNumber":{"type":"string","maxLength":25,"description":"Value used by your customer to identify the order. This value is typically a purchase order number. CyberSource\nrecommends that you do not populate the field with all zeros or nines.\n\nFor processor-specific information, see the user_po field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseOrderDate":{"type":"string","maxLength":10,"description":"Date the order was processed. `Format: YYYY-MM-DD`.\n\nFor processor-specific information, see the purchaser_order_date field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseContactName":{"type":"string","maxLength":36,"description":"The name of the individual or the company contacted for company authorized purchases.\n\nFor processor-specific information, see the authorized_contact_name field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxable":{"type":"boolean","description":"Flag that indicates whether an order is taxable. This value must be true if the sum of all _lineItems[].taxAmount_ values > 0.\n\nIf you do not include any _lineItems[].taxAmount_ values in your request, CyberSource does not include\n_invoiceDetails.taxable_ in the data it sends to the processor.\n\nFor processor-specific information, see the tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]},"vatInvoiceReferenceNumber":{"type":"string","maxLength":15,"description":"VAT invoice number associated with the transaction.\n\nFor processor-specific information, see the vat_invoice_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"commodityCode":{"type":"string","maxLength":4,"description":"International description code of the overall order\u2019s goods or services or the Categorizes purchases for VAT\nreporting. Contact your acquirer for a list of codes.\n\nFor processor-specific information, see the summary_commodity_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"merchandiseCode":{"type":"number","description":"Identifier for the merchandise. Possible value:\n\n - 1000: Gift card\n\nThis field is supported only for **American Express Direct**.\n"},"transactionAdviceAddendum":{"type":"array","items":{"type":"object","properties":{"data":{"type":"string","maxLength":40,"description":"Four Transaction Advice Addendum (TAA) fields. These fields are used to display descriptive information\nabout a transaction on the customer\u2019s American Express card statement. When you send TAA fields, start\nwith amexdata_taa1, then ...taa2, and so on. Skipping a TAA field causes subsequent TAA fields to be\nignored.\n\nTo use these fields, contact CyberSource Customer Support to have your account enabled for this feature.\n"}}}}}},"shippingDetails":{"type":"object","properties":{"giftWrap":{"type":"boolean","description":"Description of this field is not available."},"shippingMethod":{"type":"string","maxLength":10,"description":"Shipping method for the product. Possible values:\n\n - lowcost: Lowest-cost service\n - sameday: Courier or same-day service\n - oneday: Next-day or overnight service\n - twoday: Two-day service\n - threeday: Three-day service\n - pickup: Store pick-up\n - other: Other shipping method\n - none: No shipping method because product is a service or subscription\n"},"shipFromPostalCode":{"type":"string","maxLength":10,"description":"Postal code for the address from which the goods are shipped, which is used to establish nexus. The default is\nthe postal code associated with your CyberSource account.\n\nThe postal code must consist of 5 to 9 digits. When the billing country is the U.S., the 9-digit postal code\nmust follow this format:\n\n`[5 digits][dash][4 digits]`\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n\n`[alpha][numeric][alpha][space] [numeric][alpha][numeric]`\n\nExample A1B 2C3\n\nThis field is frequently used for Level II and Level III transactions.\n"}}}}},"buyerInformation":{"type":"object","properties":{"merchantCustomerId":{"type":"string","maxLength":100,"description":"Your identifier for the customer.\n\nFor processor-specific information, see the customer_account_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"dateOfBirth":{"type":"string","maxLength":8,"description":"Recipient\u2019s date of birth. **Format**: `YYYYMMDD`.\n\nThis field is a pass-through, which means that CyberSource ensures that the value is eight numeric characters\nbut otherwise does not verify the value or modify it in any way before sending it to the processor. If the field\nis not required for the transaction, CyberSource does not forward it to the processor.\n"},"vatRegistrationNumber":{"type":"string","maxLength":20,"description":"Customer\u2019s government-assigned tax identification number.\n\nFor processor-specific information, see the purchaser_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"personalIdentification":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["ssn","driverlicense"]},"id":{"type":"string","maxLength":26,"description":"Personal Identifier for the customer based on various type. This field is supported only on the processors\nlisted in this description.\n\nFor processor-specific information, see the personal_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"issuedBy":{"type":"string","description":"Description of this field is not available."}}}},"hashedPassword":{"type":"string","maxLength":100,"description":"TODO\n"}}},"recipientInformation":{"type":"object","properties":{"accountId":{"type":"string","maxLength":10,"description":"Identifier for the recipient\u2019s account. Use the first six digits and last four digits of the recipient\u2019s account\nnumber. This field is a pass-through, which means that CyberSource does not verify the value or modify it in\nany way before sending it to the processor. If the field is not required for the transaction, CyberSource does\nnot forward it to the processor.\n"},"lastName":{"type":"string","maxLength":6,"description":"Recipient\u2019s last name. This field is a passthrough, which means that CyberSource does not verify the value or\nmodify it in any way before sending it to the processor. If the field is not required for the transaction,\nCyberSource does not forward it to the processor.\n"},"postalCode":{"type":"string","maxLength":6,"description":"Partial postal code for the recipient\u2019s address. For example, if the postal code is **NN5 7SG**, the value for\nthis field should be the first part of the postal code: **NN5**. This field is a pass-through, which means that\nCyberSource does not verify the value or modify it in any way before sending it to the processor. If the field\nis not required for the transaction, CyberSource does not forward it to the processor.\n"}}},"deviceInformation":{"type":"object","properties":{"hostName":{"type":"string","maxLength":60,"description":"DNS resolved hostname from above _ipAddress_."},"ipAddress":{"type":"string","maxLength":15,"description":"IP address of the customer."},"userAgent":{"type":"string","maxLength":40,"description":"Customer\u2019s browser as identified from the HTTP header data. For example, Mozilla is the value that identifies\nthe Netscape browser.\n"}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"name":{"type":"string","maxLength":23,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\nFor Payouts:\n* Paymentech (22)\n"},"alternateName":{"type":"string","maxLength":13,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"contact":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n* FDCCompass (13)\n* Paymentech (13)\n"},"address1":{"type":"string","maxLength":60,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":13,"description":"Merchant City. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":3,"description":"Merchant State. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"salesOrganizationId":{"type":"string","maxLength":11,"description":"Company ID assigned to an independent sales organization. Get this value from Mastercard.\n\nFor processor-specific information, see the sales_organization_ID field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"categoryCode":{"type":"integer","maximum":9999,"description":"Four-digit number that the payment card industry uses to classify merchants into market segments. Visa assigned\none or more of these values to your business when you started accepting Visa cards.\n\nIf you do not include this field in your request, CyberSource uses the value in your CyberSource account.\n\nFor processor-specific information, see the merchant_category_code field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":21,"description":"Your government-assigned tax identification number.\n\nFor CtV processors, the maximum length is 20.\n\nFor other processor-specific information, see the merchant_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"cardAcceptorReferenceNumber":{"type":"string","maxLength":25,"description":"Reference number that facilitates card acceptor/corporation communication and record keeping.\n\nFor processor-specific information, see the card_acceptor_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"transactionLocalDateTime":{"type":"string","maxLength":14,"description":"Local date and time at your physical location. Include both the date and time in this field or leave it blank.\nThis field is supported only for **CyberSource through VisaNet**.\n\nFor processor-specific information, see the transaction_local_date_time field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\n`Format: YYYYMMDDhhmmss`, where:\n\n - YYYY = year\n - MM = month\n - DD = day\n - hh = hour\n - mm = minutes\n - ss = seconds\n"}}},"aggregatorInformation":{"type":"object","properties":{"aggregatorId":{"type":"string","maxLength":20,"description":"Value that identifies you as a payment aggregator. Get this value from the\nprocessor.\n\nFor processor-specific information, see the aggregator_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"name":{"type":"string","maxLength":37,"description":"Your payment aggregator business name.\n\nFor processor-specific information, see the aggregator_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"subMerchant":{"type":"object","properties":{"cardAcceptorId":{"type":"string","maxLength":15,"description":"Unique identifier assigned by the payment card company to the sub-merchant."},"name":{"type":"string","maxLength":37,"description":"Sub-merchant\u2019s business name."},"address1":{"type":"string","maxLength":38,"description":"First line of the sub-merchant\u2019s street address."},"locality":{"type":"string","maxLength":21,"description":"Sub-merchant\u2019s city."},"administrativeArea":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s state or province. Use the State, Province, and Territory Codes for the United States and Canada.\n"},"region":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s region. Example `NE` indicates that the sub-merchant is in the northeast region."},"postalCode":{"type":"string","maxLength":15,"description":"Partial postal code for the sub-merchant\u2019s address."},"country":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s country. Use the two-character ISO Standard Country Codes."},"email":{"type":"string","maxLength":40,"description":"Sub-merchant\u2019s email address.\n\n**Maximum length for processors**\n\n - American Express Direct: 40\n - CyberSource through VisaNet: 40\n - FDC Compass: 40\n - FDC Nashville Global: 19\n"},"phoneNumber":{"type":"string","maxLength":20,"description":"Sub-merchant\u2019s telephone number.\n\n**Maximum length for procesors**\n\n - American Express Direct: 20\n - CyberSource through VisaNet: 20\n - FDC Compass: 13\n - FDC Nashville Global: 10\n"}}}}},"consumerAuthenticationInformation":{"type":"object","properties":{"cavv":{"type":"string","maxLength":40,"description":"Cardholder authentication verification value (CAVV)."},"cavvAlgorithm":{"type":"string","maxLength":1,"description":"Algorithm used to generate the CAVV for Verified by Visa or the UCAF authentication\ndata for Mastercard SecureCode.\n"},"eciRaw":{"type":"string","maxLength":2,"description":"Raw electronic commerce indicator (ECI)."},"paresStatus":{"type":"string","maxLength":1,"description":"Payer authentication response status."},"veresEnrolled":{"type":"string","maxLength":1,"description":"Verification response enrollment status."},"xid":{"type":"string","maxLength":40,"description":"Transaction identifier."},"ucafAuthenticationData":{"type":"string","maxLength":32,"description":"Universal cardholder authentication field (UCAF) data."},"ucafCollectionIndicator":{"type":"string","maxLength":1,"description":"Universal cardholder authentication field (UCAF) collection indicator."}}},"pointOfSaleInformation":{"type":"object","properties":{"terminalId":{"type":"string","maxLength":8,"description":"Identifier for the terminal at your retail location. You can define this value yourself, but consult the\nprocessor for requirements.\n\nFor Payouts: This field is applicable for CtV.\n"},"terminalSerialNumber":{"type":"string","description":"Description of this field is not available."},"laneNumber":{"type":"string","maxLength":8,"description":"Identifier for an alternate terminal at your retail location. You define the value for this field.\n\nThis field is supported only for MasterCard transactions on FDC Nashville Global. Use the _terminalID_ field to\nidentify the main terminal at your retail location. If your retail location has multiple terminals, use this\n_alternateTerminalID_ field to identify the terminal used for the transaction.\n\nThis field is a pass-through, which means that CyberSource does not check the value or modify the value in any\nway before sending it to the processor.\n"},"cardPresent":{"type":"boolean","description":"Indicates whether the card is present at the time of the transaction. Possible values:\n\n - **true**: Card is present.\n - **false**: Card is not present.\n"},"catLevel":{"type":"integer","minimum":1,"maximum":9,"description":"Type of cardholder-activated terminal. Possible values:\n\n - 1: Automated dispensing machine\n - 2: Self-service terminal\n - 3: Limited amount terminal\n - 4: In-flight commerce (IFC) terminal\n - 5: Radio frequency device\n - 6: Mobile acceptance terminal\n - 7: Electronic cash register\n - 8: E-commerce device at your location\n - 9: Terminal or cash register that uses a dialup connection to connect to the transaction processing network\n * Applicable only for CTV for Payouts.\n"},"entryMode":{"type":"string","maxLength":11,"description":"Method of entering credit card information into the POS terminal. Possible values:\n\n - contact: Read from direct contact with chip card.\n - contactless: Read from a contactless interface using chip data.\n - keyed: Manually keyed into POS terminal.\n - msd: Read from a contactless interface using magnetic stripe data (MSD).\n - swiped: Read from credit card magnetic stripe.\n\nThe contact, contactless, and msd values are supported only for EMV transactions.\n* Applicable only for CTV for Payouts.\n"},"terminalCapability":{"type":"integer","minimum":1,"maximum":5,"description":"POS terminal\u2019s capability. Possible values:\n\n - 1: Terminal has a magnetic stripe reader only.\n - 2: Terminal has a magnetic stripe reader and manual entry capability.\n - 3: Terminal has manual entry capability only.\n - 4: Terminal can read chip cards.\n - 5: Terminal can read contactless chip cards.\n\nThe values of 4 and 5 are supported only for EMV transactions.\n* Applicable only for CTV for Payouts. \n"},"pinEntryCapability":{"type":"integer","minimum":1,"maximum":1,"description":"A one-digit code that identifies the capability of terminal to capture PINs. \nThis code does not necessarily mean that a PIN was entered or is included in this message. \nFor Payouts: This field is applicable for CtV.\n"},"operatingEnvironment":{"type":"string","maxLength":1,"description":"Operating environment. Possible values:\n\n - 0: No terminal used or unknown environment.\n - 1: On merchant premises, attended.\n - 2: On merchant premises, unattended, or cardholder terminal. Examples: oil, kiosks, self-checkout, home\n computer, mobile telephone, personal digital assistant (PDA). Cardholder terminal is supported only for\n MasterCard transactions on **CyberSource through VisaNet**.\n - 3: Off merchant premises, attended. Examples: portable POS devices at trade shows, at service calls, or in\n taxis.\n - 4: Off merchant premises, unattended, or cardholder terminal. Examples: vending machines, home computer,\n mobile telephone, PDA. Cardholder terminal is supported only for MasterCard transactions on **CyberSource\n through VisaNet**.\n - 5: On premises of cardholder, unattended.\n - 9: Unknown delivery mode.\n - S: Electronic delivery of product. Examples: music, software, or eTickets that are downloaded over the\n internet.\n - T: Physical delivery of product. Examples: music or software that is delivered by mail or by a courier.\n\nThis field is supported only for **American Express Direct** and **CyberSource through VisaNet**.\n\n**CyberSource through VisaNet**\n\nFor MasterCard transactions, the only valid values are 2 and 4.\n"},"emv":{"type":"object","properties":{"tags":{"type":"string","maxLength":1998,"description":"EMV data that is transmitted from the chip card to the issuer, and from the issuer to the chip card. The EMV\ndata is in the tag-length-value format and includes chip card tags, terminal tags, and transaction detail tags.\n\n`Important` The following tags contain sensitive information and **must not** be included in this field:\n\n - **56**: Track 1 equivalent data\n - **57**: Track 2 equivalent data\n - **5A**: Application PAN\n - **5F20**: Cardholder name\n - **5F24**: Application expiration date (This sensitivity has been relaxed for cmcic, amexdirect, fdiglobal, opdfde, six)\n - **99**: Transaction PIN\n - **9F0B**: Cardholder name (extended)\n - **9F1F**: Track 1 discretionary data\n - **9F20**: Track 2 discretionary data\n\nFor captures, this field is required for contact EMV transactions. Otherwise, it is optional.\n\nFor credits, this field is required for contact EMV stand-alone credits and contactless EMV stand-alone credits.\nOtherwise, it is optional.\n\n`Important` For contact EMV captures, contact EMV stand-alone credits, and contactless EMV stand-alone credits,\nyou must include the following tags in this field. For all other types of EMV transactions, the following tags\nare optional.\n\n - **95**: Terminal verification results\n - **9F10**: Issuer application data\n - **9F26**: Application cryptogram\n"},"cardholderVerificationMethod":{"type":"number","description":"Method that was used to verify the cardholder's identity. Possible values:\n\n - **0**: No verification\n - **1**: Signature\n\nThis field is supported only on **American Express Direct**.\n"},"cardSequenceNumber":{"type":"string","maxLength":3,"description":"Number assigned to a specific card when two or more cards are associated with the same primary account number.\nThis value enables issuers to distinguish among multiple cards that are linked to the same account. This value\ncan also act as a tracking tool when reissuing cards. When this value is available, it is provided by the chip\nreader. When the chip reader does not provide this value, do not include this field in your request.\n"},"fallback":{"type":"boolean","maxLength":5,"description":"Indicates whether a fallback method was used to enter credit card information into the POS terminal. When a\ntechnical problem prevents a successful exchange of information between a chip card and a chip-capable terminal:\n\n 1. Swipe the card or key the credit card information into the POS terminal.\n 2. Use the pos_entry_mode field to indicate whether the information was swiped or keyed.\n\nThis field is supported only on **Chase Paymentech Solutions** and **GPN**.\n","enum":[true,false],"default":false},"fallbackCondition":{"type":"number","description":"Reason for the EMV fallback transaction. An EMV fallback transaction occurs when an EMV transaction fails for\none of these reasons:\n\n - Technical failure: the EMV terminal or EMV card cannot read and process chip data.\n - Empty candidate list failure: the EMV terminal does not have any applications in common with the EMV card.\n EMV terminals are coded to determine whether the terminal and EMV card have any applications in common.\n EMV terminals provide this information to you.\n\nPossible values:\n\n - **1**: Transaction was initiated with information from a magnetic stripe, and the previous transaction at the\n EMV terminal either used information from a successful chip read or it was not a chip transaction.\n - **2**: Transaction was initiated with information from a magnetic stripe, and the previous transaction at the\n EMV terminal was an EMV fallback transaction because the attempted chip read was unsuccessful.\n\nThis field is supported only on **GPN**.\n"}}},"amexCapnData":{"type":"string","maxLength":12,"description":"Point-of-sale details for the transaction. This value is returned only for **American Express Direct**.\nCyberSource generates this value, which consists of a series of codes that identify terminal capability,\nsecurity data, and specific conditions present at the time the transaction occurred. To comply with the CAPN\nrequirements, this value must be included in all subsequent follow-on requests, such as captures and follow-on\ncredits.\n\nWhen you perform authorizations, captures, and credits through CyberSource, CyberSource passes this value from\nthe authorization service to the subsequent services for you. However, when you perform authorizations through\nCyberSource and perform subsequent services through other financial institutions, you must ensure that your\nrequests for captures and credits include this value.\n"},"trackData":{"type":"string","description":"Card\u2019s track 1 and 2 data. For all processors except FDMS Nashville, this value consists of\none of the following:\n\n - Track 1 data\n - Track 2 data\n - Data for both tracks 1 and 2\n\nFor FDMS Nashville, this value consists of one of the following:\n - Track 1 data\n - Data for both tracks 1 and 2\n\nExample: %B4111111111111111^SMITH/JOHN ^1612101976110000868000000?;4111111111111111=16121019761186800000?\n"}}},"merchantDefinedInformation":{"type":"array","description":"Description of this field is not available.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":50,"description":"Description of this field is not available."},"value":{"type":"string","maxLength":255,"description":"Description of this field is not available."}}}}},"example":{"clientReferenceInformation":{"code":"TC50171_3"},"processingInformation":{"commerceIndicator":"internet"},"aggregatorInformation":{"subMerchant":{"cardAcceptorId":"1234567890","country":"US","phoneNumber":"650-432-0000","address1":"900 Metro Center","postalCode":"94404-2775","locality":"Foster City","name":"Visa Inc","administrativeArea":"CA","region":"PEN","email":"test@cybs.com"},"name":"V-Internatio","aggregatorId":"123456789"},"orderInformation":{"billTo":{"country":"US","lastName":"Doe","address2":"Address 2","address1":"201 S. Division St.","postalCode":"48104-2201","locality":"Ann Arbor","administrativeArea":"MI","firstName":"John","phoneNumber":"999999999","district":"MI","buildingNumber":"123","company":"Visa","email":"test@cybs.com"},"amountDetails":{"totalAmount":"102.21","currency":"USD"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"5555555555554444","securityCode":"123","expirationMonth":"12","type":"002"}}}}}],"responses":{"201":{"description":"Successful response.","schema":{"type":"object","title":"ptsV2PaymentsPost201Response","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}},"reversal":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}},"capture":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["AUTHORIZED","PARTIAL_AUTHORIZED","AUTHORIZED_PENDING_REVIEW","DECLINED"]},"reconciliationId":{"type":"string","maxLength":60,"description":"The reconciliation id for the submitted transaction. This value is not returned for all processors.\n"},"errorInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The reason of the status.\n","enum":["AVS_FAILED","CONTACT_PROCESSOR","CV_FAILED","EXPIRED_CARD","PROCESSOR_DECLINED","INSUFFICIENT_FUND","STOLEN_LOST_CARD","ISSUER_UNAVAILABLE","UNAUTHORIZED_CARD","CVN_NOT_MATCH","EXCEEDS_CREDIT_LIMIT","INVALID_CVN","PAYMENT_REFUSED","INVALID_ACCOUNT","GENERAL_DECLINE"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"processorInformation":{"type":"object","properties":{"approvalCode":{"type":"string","description":"Authorization code. Returned only when the processor returns this value.\n"},"transactionId":{"type":"string","maxLength":50,"description":"Network transaction identifier (TID). You can use this value to identify a specific transaction when you are\ndiscussing the transaction with your processor. Not all processors provide this value.\n"},"networkTransactionId":{"type":"string","description":"Description of this field is not available."},"providerTransactionId":{"type":"string","description":"Description of this field is not available."},"responseCode":{"type":"string","maxLength":10,"description":"For most processors, this is the error message sent directly from the bank. Returned only when the processor\nreturns this value.\n\nImportant Do not use this field to evaluate the result of the authorization.\n"},"responseCodeSource":{"type":"string","maxLength":1,"description":"Used by Visa only and contains the response source/reason code that identifies the source of the response decision.\n"},"responseDetails":{"type":"string","maxLength":255,"description":"This field might contain information about a decline. This field is supported only for **CyberSource through\nVisaNet**.\n"},"responseCategoryCode":{"type":"string","maxLength":32,"description":"Processor-defined response category code. The associated detail error code is in the auth_auth_response\nfield or the auth_reversal_auth_ response field depending on which service you requested.\n\nThis field is supported only for:\n\n - Japanese issuers\n - Domestic transactions in Japan\n - Comercio Latino\u2014processor transaction ID required for troubleshooting\n\n**Maximum length for processors**:\n\n - Comercio Latino: 32\n - All other processors: 3\n"},"forwardedAcquirerCode":{"type":"string","maxLength":32,"description":"Name of the Japanese acquirer that processed the transaction. Returned only for CCS (CAFIS) and JCN Gateway.\nPlease contact the CyberSource Japan Support Group for more information.\n"},"avs":{"type":"object","properties":{"code":{"type":"string","maxLength":1,"description":"AVS result code.\n"},"codeRaw":{"type":"string","maxLength":10,"description":"AVS result code sent directly from the processor. Returned only when the processor returns this value.\nImportant Do not use this field to evaluate the result of AVS. Use for debugging purposes only.\n"}}},"cardVerification":{"type":"object","properties":{"resultCode":{"type":"string","maxLength":1,"description":"CVN result code.\n"},"resultCodeRaw":{"type":"string","maxLength":10,"description":"CVN result code sent directly from the processor. Returned only when the processor returns this value.\n\n`Important` Do not use this field to evaluate the result of card verification. Use for debugging purposes only.\n"}}},"merchantAdvice":{"type":"object","properties":{"code":{"type":"string","maxLength":2,"description":"Reason the recurring payment transaction was declined. For some processors, this field is used only for\nMastercard. For other processors, this field is used for Visa and Mastercard. And for other processors, this\nfield is not implemented.\n\nPossible values:\n\n - **00**: Response not provided.\n - **01**: New account information is available. Obtain the new information.\n - **02**: Try again later.\n - **03**: Do not try again. Obtain another type of payment from the customer.\n - **04**: Problem with a token or a partial shipment indicator.\n - **21**: Recurring payment cancellation service.\n - **99**: An unknown value was returned from the processor.\n"},"codeRaw":{"type":"string","maxLength":2,"description":"Raw merchant advice code sent directly from the processor. This field is used only for Mastercard.\n\nFor processor-specific information, see the auth_merchant_advice_code_raw field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"electronicVerificationResults":{"type":"object","properties":{"code":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s name.\n"},"codeRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s last name"},"email":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s email address.\n"},"emailRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s email address."},"phoneNumber":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s phone number.\n"},"phoneNumberRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s phone number."},"postalCode":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s postal code.\n"},"postalCodeRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s postal code."},"street":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s street address.\n"},"streetRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s street address."},"name":{"type":"string","maxLength":30,"description":"TODO\n"},"nameRaw":{"type":"string","maxLength":30,"description":"TODO"}}},"customer":{"type":"object","properties":{"personalIdResult":{"type":"string","maxLength":1,"description":"Personal identifier result. This field is supported only for Redecard in Brazil for CyberSource Latin\nAmerican Processing. If you included _buyerInformation.personalIdentification[].ID_ in the request, this\nvalue indicates whether or not _buyerInformation.personalIdentification[].ID_ matched a value in a record\non file. Returned only when the personal ID result is returned by the processor.\n\nPossible values:\n\n - **Y**: Match\n - **N**: No match\n - **K**: Not supported\n - **U**: Unknown\n - **Z**: No response returned\n"}}},"consumerAuthenticationResponse":{"type":"object","properties":{"code":{"type":"string","maxLength":3,"description":"Mapped response code for Verified by Visa and American Express SafeKey:\n"},"codeRaw":{"type":"string","maxLength":3,"description":"Raw response code sent directly from the processor for Verified by Visa and American Express SafeKey:\n"}}},"issuer":{"type":"object","properties":{"country":{"type":"string","maxLength":3,"description":"Country in which the card was issued. This information enables you to determine whether the card was issued\ndomestically or internationally. Use the two-character ISO Standard Country Codes.\n\nThis field is supported for Visa, Mastercard, Discover, Diners Club, JCB, and Maestro (International) on Chase\nPaymentech Solutions.\n"},"discretionaryData":{"type":"string","maxLength":255,"description":"Data defined by the issuer. The value for this reply field will probably be the same as the value that you\nsubmitted in the authorization request, but it is possible for the processor, issuer, or acquirer to modify\nthe value.\n\nThis field is supported only for Visa transactions on **CyberSource through VisaNet**.\n"}}},"systemTraceAuditNumber":{"type":"string","maxLength":6,"description":"This field is returned only for **American Express Direct** and **CyberSource through VisaNet**.\n\n**American Express Direct**\n\nSystem trace audit number (STAN). This value identifies the transaction and is useful when investigating a\nchargeback dispute.\n\n**CyberSource through VisaNet**\n\nSystem trace number that must be printed on the customer\u2019s receipt.\n"},"paymentAccountReferenceNumber":{"type":"string","maxLength":32,"description":"Visa-generated reference number that identifies a card-present transaction for which youprovided one of the\nfollowing:\n\n - Visa primary account number (PAN)\n - Visa-generated token for a PAN\n\nThis reference number serves as a link to the cardholder account and to all transactions for that account.\n"},"transactionIntegrityCode":{"type":"string","maxLength":2,"description":"Transaction integrity classification provided by Mastercard. This value specifies Mastercard\u2019s evaluation of\nthe transaction\u2019s safety and security. This field is returned only for **CyberSource through VisaNet**.\n\nFor card-present transactions, possible values:\n\n - **A1**: EMV or token in a secure, trusted environment\n - **B1**: EMV or chip equivalent\n - **C1**: Magnetic stripe\n - **E1**: Key entered\n - **U0**: Unclassified\n\nFor card-not-present transactions, possible values:\n\n - **A2**: Digital transactions\n - **B2**: Authenticated checkout\n - **C2**: Transaction validation\n - **D2**: Enhanced data\n - **E2**: Generic messaging\n - **U0**: Unclassified\n\nFor information about these values, contact Mastercard or your acquirer.\n"},"amexVerbalAuthReferenceNumber":{"type":"string","maxLength":6,"description":"Referral response number for a verbal authorization with FDMS Nashville when using an American Express card.\nGive this number to American Express when you call them for the verbal authorization.\n"},"salesSlipNumber":{"type":"number","maximum":99999,"description":"Transaction identifier that CyberSource generates. You have the option of printing the sales slip number on\nthe receipt.\n\nThis field is supported only for **JCN Gateway**.\n"},"masterCardServiceCode":{"type":"string","maxLength":2,"description":"Mastercard service that was used for the transaction. Mastercard provides this value to CyberSource.\n\nPossible value:\n - 53: Mastercard card-on-file token service\n"},"masterCardServiceReplyCode":{"type":"string","maxLength":1,"description":"Result of the Mastercard card-on-file token service. Mastercard provides this value to CyberSource.\n\nPossible values:\n\n - **C**: Service completed successfully.\n - **F**: One of the following:\n - Incorrect Mastercard POS entry mode. The Mastercard POS entry mode should be 81 for an authorization or\n authorization reversal.\n - Incorrect Mastercard POS entry mode. The Mastercard POS entry mode should be 01 for a tokenized request.\n - Token requestor ID is missing or formatted incorrectly.\n - **I**: One of the following:\n - Invalid token requestor ID.\n - Suspended or deactivated token.\n - Invalid token (not in mapping table).\n - **T**: Invalid combination of token requestor ID and token.\n - **U**: Expired token.\n - **W**: Primary account number (PAN) listed in electronic warning bulletin.\n\nNote This field is returned only for **CyberSource through VisaNet**.\n"},"masterCardAuthenticationType":{"type":"string","maxLength":1,"description":"Type of authentication for which the transaction qualifies as determined by the Mastercard authentication\nservice, which confirms the identity of the cardholder. Mastercard provides this value to CyberSource.\n\nPossible values:\n\n - **1**: Transaction qualifies for Mastercard authentication type 1.\n - **2**: Transaction qualifies for Mastercard authentication type 2.\n"},"name":{"type":"string","maxLength":30,"description":"Name of the Processor.\n"}}},"paymentInformation":{"type":"object","properties":{"card":{"type":"object","properties":{"suffix":{"type":"string","maxLength":4,"description":"Last four digits of the cardholder\u2019s account number. This field is returned only for tokenized transactions.\nYou can use this value on the receipt that you give to the cardholder.\n"}}},"tokenizedCard":{"type":"object","properties":{"prefix":{"type":"string","maxLength":6,"description":"First six digits of token. CyberSource includes this field in the reply message when it decrypts the payment\nblob for the tokenized transaction.\n"},"suffix":{"type":"string","maxLength":4,"description":"Last four digits of token. CyberSource includes this field in the reply message when it decrypts the payment\nblob for the tokenized transaction.\n"},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"},"assuranceLevel":{"type":"string","maxLength":2,"description":"Confidence level of the tokenization. This value is assigned by the token service provider.\n\n`Note` This field is supported only for **CyberSource through VisaNet** and **FDC Nashville Global**.\n"},"expirationMonth":{"type":"string","maxLength":2,"description":"Two-digit month in which the payment network token expires. `Format: MM`. Possible values: 01 through 12.\n"},"expirationYear":{"type":"string","maxLength":4,"description":"Four-digit year in which the payment network token expires. `Format: YYYY`.\n"},"requestorId":{"type":"string","maxLength":11,"description":"Value that identifies your business and indicates that the cardholder\u2019s account number is tokenized. This value\nis assigned by the token service provider and is unique within the token service provider\u2019s database.\n\n`Note` This field is supported only for **CyberSource through VisaNet** and **FDC Nashville Global**.\n"}}},"accountFeatures":{"type":"object","properties":{"accountType":{"type":"string","maxLength":2,"description":"Type of account. This value is returned only if you requested a balance inquiry. Possible values:\n\n - **00**: Not applicable or not specified\n - **10**: Savings account\n - **20**: Checking account\n - **30**: Credit card account\n - **40**: Universal account\n"},"accountStatus":{"type":"string","maxLength":1,"description":"Possible values:\n\n - **N**: Nonregulated\n - **R**: Regulated\n\n`Note` This field is returned only for CyberSource through VisaNet.\n"},"balanceAmount":{"type":"string","maxLength":12,"description":"Remaining balance on the account.\n"},"balanceAmountType":{"type":"string","maxLength":2,"description":"Type of amount. This value is returned only if you requested a balance inquiry. The issuer determines the value\nthat is returned. Possible values for deposit accounts:\n\n - **01**: Current ledger (posted) balance.\n - **02**: Current available balance, which is typically the ledger balance less outstanding authorizations.\n\nSome depository institutions also include pending deposits and the credit or overdraft line associated with the\naccount. Possible values for credit card accounts:\n\n - **01**: Credit amount remaining for customer (open to buy).\n - **02**: Credit limit.\n"},"currency":{"type":"string","maxLength":5,"description":"Currency of the remaining balance on the account. For the possible values, see the ISO Standard Currency Codes.\n"},"balanceSign":{"type":"string","maxLength":1,"description":"Sign for the remaining balance on the account. Returned only when the processor returns this value. Possible values:\n","enum":["+","-"]},"affluenceIndicator":{"type":"string","maxLength":13,"description":"**Chase Paymentech Solutions**\n\nIndicates whether a customer has high credit limits. This information enables you to market high cost items to\nthese customers and to understand the kinds of cards that high income customers are using.\n\nThis field is supported for Visa, Mastercard, Discover, and Diners Club. Possible values:\n\n - **Y**: Yes\n - **N**: No\n - **X**: Not applicable / Unknown\n\n**Litle**\n\nFlag that indicates that a Visa cardholder or Mastercard cardholder is in one of the affluent categories.\nPossible values:\n\n - **AFFLUENT**: High income customer with high spending pattern (>100k USD annual income and >40k USD annual\n card usage).\n - **MASS AFFLUENT**: High income customer (>100k USD annual income).\n\n**Processor specific maximum length**:\n\n - Chase Paymentech Solutions: 1\n - Litle: 13\n"},"category":{"type":"string","maxLength":7,"description":"**CyberSource through VisaNet**\n\nVisa product ID.\n\n**GPN**\n\nVisa or Mastercard product ID.\n\n**Litle**\n\nType of card used in the transaction. The only possible value is:\n\n - PREPAID: Prepaid Card\n\n**RBS WorldPay Atlanta**\n\nType of card used in the transaction. Possible values:\n\n - **B**: Business Card\n - **O**: Noncommercial Card\n - **R**: Corporate Card\n - **S**: Purchase Card\n - **Blank**: Purchase card not supported\n\n**Maximum length for processors**:\n\n - CyberSource through VisaNet: 3\n - GPN: 3\n - Litle: 7\n - RBS WorldPay Atlanta: 1\n"},"commercial":{"type":"string","maxLength":1,"description":"Indicates whether the card is a commercial card, which enables you to include Level II data in your transaction\nrequests. This field is supported for Visa and Mastercard on **Chase Paymentech Solutions**. Possible values:\n\n - **Y**: Yes\n - **N**: No\n - **X**: Not applicable / Unknown\n"},"group":{"type":"string","maxLength":1,"description":"Type of commercial card. This field is supported only for CyberSource through VisaNet. Possible values:\n\n - **B**: Business card\n - **R**: Corporate card\n - **S**: Purchasing card\n - **0**: Noncommercial card\n"},"healthCare":{"type":"string","maxLength":1,"description":"Indicates whether the card is a healthcare card. This field is supported for Visa and Mastercard on **Chase\nPaymentech Solutions**. Possible values:\n\n - **Y**: Yes\n - **N**: No\n - **X**: Not applicable / Unknown\n"},"payroll":{"type":"string","maxLength":1,"description":"Indicates whether the card is a payroll card. This field is supported for Visa, Discover, Diners Club, and JCB\non **Chase Paymentech Solutions**. Possible values:\n\n - **Y**: Yes\n - **N**: No\n - **X**: Not applicable / Unknown\n"},"level3Eligible":{"type":"string","maxLength":1,"description":"Indicates whether the card is eligible for Level III interchange fees, which enables you to include Level III\ndata in your transaction requests. This field is supported for Visa and Mastercard on **Chase Paymentech\nSolutions**. Possible values:\n\n - **Y**: Yes\n - **N**: No\n - **X**: Not applicable / Unknown\n"},"pinlessDebit":{"type":"string","maxLength":1,"description":"Indicates whether the card is a PINless debit card. This field is supported for Visa and Mastercard on **Chase\nPaymentech Solutions**. Possible values:\n\n - **Y**: Yes\n - **N**: No\n - **X**: Not applicable / Unknown\n"},"signatureDebit":{"type":"string","maxLength":1,"description":"Indicates whether the card is a signature debit card. This information enables you to alter the way an order is\nprocessed. For example, you might not want to reauthorize a transaction for a signature debit card, or you might\nwant to perform reversals promptly for a signature debit card. This field is supported for Visa, Mastercard, and\nMaestro (International) on Chase Paymentech Solutions. Possible values:\n\n - **Y**: Yes\n - **N**: No\n - **X**: Not applicable / Unknown\n"},"prepaid":{"type":"string","maxLength":1,"description":"Indicates whether the card is a prepaid card. This information enables you to determine when a gift card or\nprepaid card is presented for use when establishing a new recurring, installment, or deferred billing\nrelationship.\n\nThis field is supported for Visa, Mastercard, Discover, Diners Club, and JCB on Chase Paymentech Solutions.\nPossible values:\n\n - **Y**: Yes\n - **N**: No\n - **X**: Not applicable / Unknown\n"},"regulated":{"type":"string","maxLength":1,"description":"Indicates whether the card is regulated according to the Durbin Amendment. If the card is regulated, the card\nissuer is subject to price caps and interchange rules. This field is supported for Visa, Mastercard, Discover,\nDiners Club, and JCB on Chase Paymentech Solutions. Possible values:\n\n - **Y**: Yes (assets greater than 10B USD)\n - **N**: No (assets less than 10B USD)\n - **X**: Not applicable / Unknown\n"}}}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":15,"description":"Amount you requested for the payment or capture.\n\nThis value is returned for partial authorizations.\n"},"authorizedAmount":{"type":"string","maxLength":15,"description":"Amount that was authorized.\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}},"invoiceDetails":{"type":"object","properties":{"level3TransmissionStatus":{"type":"boolean","description":"Indicates whether CyberSource sent the Level III information to the processor. The possible values are:\n\nIf your account is not enabled for Level III data or if you did not include the purchasing level field in your\nrequest, CyberSource does not include the Level III data in the request sent to the processor.\n\nFor processor-specific information, see the bill_purchasing_level3_enabled field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]}}}}},"pointOfSaleInformation":{"type":"object","properties":{"emv":{"type":"object","properties":{"tags":{"type":"string","maxLength":1998,"description":"EMV data that is transmitted from the chip card to the issuer, and from the issuer to the chip card. The EMV\ndata is in the tag-length-value format and includes chip card tags, terminal tags, and transaction detail tags.\n\n`Important` The following tags contain sensitive information and **must not** be included in this field:\n\n - **56**: Track 1 equivalent data\n - **57**: Track 2 equivalent data\n - **5A**: Application PAN\n - **5F20**: Cardholder name\n - **5F24**: Application expiration date (This sensitivity has been relaxed for cmcic, amexdirect, fdiglobal, opdfde, six)\n - **99**: Transaction PIN\n - **9F0B**: Cardholder name (extended)\n - **9F1F**: Track 1 discretionary data\n - **9F20**: Track 2 discretionary data\n\nFor captures, this field is required for contact EMV transactions. Otherwise, it is optional.\n\nFor credits, this field is required for contact EMV stand-alone credits and contactless EMV stand-alone credits.\nOtherwise, it is optional.\n\n`Important` For contact EMV captures, contact EMV stand-alone credits, and contactless EMV stand-alone credits,\nyou must include the following tags in this field. For all other types of EMV transactions, the following tags\nare optional.\n\n - **95**: Terminal verification results\n - **9F10**: Issuer application data\n - **9F26**: Application cryptogram\n"}}},"amexCapnData":{"type":"string","maxLength":12,"description":"Point-of-sale details for the transaction. This value is returned only for **American Express Direct**.\nCyberSource generates this value, which consists of a series of codes that identify terminal capability,\nsecurity data, and specific conditions present at the time the transaction occurred. To comply with the CAPN\nrequirements, this value must be included in all subsequent follow-on requests, such as captures and follow-on\ncredits.\n\nWhen you perform authorizations, captures, and credits through CyberSource, CyberSource passes this value from\nthe authorization service to the subsequent services for you. However, when you perform authorizations through\nCyberSource and perform subsequent services through other financial institutions, you must ensure that your\nrequests for captures and credits include this value.\n"}}}},"example":{"_links":{"self":{"href":"/pts/v2/payments/4963015972176007901546","method":"GET"},"authReversal":{"href":"/pts/v2/payments/4963015972176007901546/reversals","method":"POST"},"capture":{"href":"/pts/v2/payments/4963015972176007901546/captures","method":"POST"},"refund":{"href":"/pts/v2/payments/4963015972176007901546/refunds","method":"POST"},"void":{"href":"/pts/v2/payments/4963015972176007901546/voids","method":"POST"}},"id":"4963015972176007901546","submitTimeUtc":"2017-06-01T071957Z","status":"200","reconciliationId":"39570726X3E1LBQR","statusInformation":{"reason":"SUCCESS","message":"Successful transaction."},"clientReferenceInformation":{"code":"TC50171_3"},"orderInformation":{"amountDetails":{"authorizedAmount":"102.21","currency":"USD"}},"processorInformation":{"approvalCode":"888888","cardVerification":{"resultCode":""},"avs":{"code":"X","codeRaw":"I1"},"responseCode":"100"}}}},"400":{"description":"Invalid request.","schema":{"type":"object","title":"ptsV2PaymentsPost400Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_CARD","CARD_TYPE_NOT_ACCEPTED","INVALID_MERCHANT_CONFIGURATION","PROCESSOR_UNAVAILABLE","INVALID_AMOUNT","INVALID_CARD_TYPE","DEBIT_CARD_USEAGE_EXCEEDD_LIMIT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"type":"object","title":"ptsV2PaymentsPost502Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Simple Authorization(Internet)","value":{"clientReferenceInformation":{"code":"TC50171_3"},"processingInformation":{"commerceIndicator":"internet"},"orderInformation":{"billTo":{"firstName":"John","lastName":"Doe","address2":"Address 2","address1":"201 S. Division St.","postalCode":"48104-2201","locality":"Ann Arbor","administrativeArea":"MI","country":"US","phoneNumber":"999999999","district":"MI","buildingNumber":"123","company":"Visa","email":"test@cybs.com"},"amountDetails":{"totalAmount":"102.21","currency":"USD"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"4111111111111111","securityCode":"123","expirationMonth":"12","type":"002"}}}},"example1":{"summary":"Simple Authorization(Retail)","value":{"clientReferenceInformation":{"code":"1234567890"},"pointOfSaleInformation":{"cardPresent":"true","catLevel":"6","emv":{"fallbackCondition":"swiped","fallback":"N"},"terminalCapability":"4"},"orderInformation":{"billTo":{"country":"US","firstName":"John","lastName":"Deo","address1":"901 Metro Center Blvd","postalCode":"40500","locality":"Foster City","administrativeArea":"CA","email":"test@cybs.com"},"amountDetails":{"totalAmount":10,"currency":"USD"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"4111111111111111","securityCode":"123","expirationMonth":"12"}}}},"example2":{"summary":"CyberSource Payment Tokenization","value":{"clientReferenceInformation":{"code":"TC_MPOS_Paymentech_3"},"processingInformation":{"commerceIndicator":"internet"},"orderInformation":{"billTo":{"country":"US","firstName":"John","lastName":"Deo","phoneNumber":"6504327113","address1":"901 Metro Center Blvd","postalCode":"94404","locality":"Foster City","administrativeArea":"CA","email":"test@cybs.com"},"amountDetails":{"totalAmount":"2719","currency":"USD"}},"paymentInformation":{"tokenizedCard":{"expirationYear":"2031","number":"4111111111111111","expirationMonth":"12","transactionType":"1"},"fluidData":{"value":"WjmY7vC+ll6uM/YEAk/LIg6B91chaJZXUOMWDnpbIjvGX0tsqYNIM4FV5Z5RpcH8NAkmHCJrMs/FIZ26pXmltDSCFEgVKTvllNmEZmC7hoqAL0mO8GAPR8pAzJVuVoN3Qdyhm099BYLI3IE+hyHqHMlMf7kNdofkSVvpi9d8eEYAWtiU62FQbzIP+dePBh4120zzCoKkUyQf5Iw8uI1axz79ctf0qSDtReopUGmTiQZwlhVNFUb6FjPTAktQfMfbpF5RJM15W9e0n0tHE+sMcJur0Isi95KYtRnsWKnNWcvMWB1p3FPRVKsV/8mmsByfnfwPyH/dS56m/+G9MNCFoAASeKi2H9cbmNetDPw0g9kOE9HXw8lcet3Uz8Q3f1TzYCniTgwuRaJ0s6o/PlpnJvVjOm/tYHfcaOrcv3RNeT9I7YCxxBgkdvJVQ03Fhk2DZPNDgzGf1jbQ+mnv+Uq70kdbrcziuxfdNMwWy8mIEAz3i3eJJEFJZtDT1EXy9glnVEKkQIFzh2HccGs+CJriXXOLG9cl/0b4tT4P7W6wb9lazhcS1imxf3G3uNGFPvejuMqM0ll9KOOOffurAJ31n5Buwkq4+YS+M9PCE0maugGQ0RfqpIjbyoAYuClndwEKPPDKVNmg+L6CGPvrUcBYh7MhFj0NqTTK4JrNYJj099Bx0u5+tz3aEnMSmNQZYFEADocxWZB+oQ/u1BkOhR6yYBDUHyFCAPl8uh8x6Y5Acpb687FtT8+Vt+GoyQJL9HzLFe3D6KxQ+I7sT71YJrf8J5rZP4rUDnFedBQEdUJh/NeZs8GE20CVwBN+E6BgTNL9dSBJFhbwJkZt5cenQtaiO/y52OltBV/8wZVuW6BxbIM1+LSEkDufCZYw5x7Ih/cwdsj0I3Q6fVcjXyehj3xbgTJ7+XTYM1vuiy6zKBpq82uHvKw4V1pYmY4n93GutFWkGskWrwwgRzcRFLgf8yGAwCFI1bif8UVUd8SAhGqNpSLiPLJC1Axn7nt+TXdNWyQwHi4YZ+eQslBkgKy2Baee/zPAz3nGEIYcxKfvbhfx2KxIlTDfcej9zoArrShtFHNu5C4PQKFvl5wl5GkuKogx/IC3J6fPZbLcdQkPE6dZz7cHhp0aAcNb8RXmadixU4hEh3WSTy9iu0Ey/ti9RQ51dJ1cJk5TcOXjJUbAVdfcxsOFs5LBOFVbZwV2du+Tfxy313s4WyHszfrD/Y6+7Zsn2zM29N8rMq0fh+y+O/dHJDVLqtYwGLEb+ZFAV+TJnZBsuTLFm2D6H/yMA009+g56x03sxhW3usjDyHblUqMiVO3yl/626lrhwbvZNRE8MI5GqcfXuIo7fJgHyfmgYWNXbfxfNzB372+lLQbrpOWBlvgaP9ZeS512nNn0EY205gzwpoSQHugwNVXj7gE9rcBpF0dBThotIk2ZxPPMabSYTZdjRmGnzzV5t4HxwAQtXJgMbiDbQRkqIdlI8i0rXuaQnDYdxhqFr6ek5nCV9ypi71rSUE/IObRux5mX7BkO2OgGZ/jHWIHDzghQTmyxmSYnaKGj3ZoeEZpMvrrLPSJWdpouCA8cDhnyfYzJydTjySeGOf95SGYQbCIJKUnI9HQJLB9HTgSOroYjpxpfSe0/5i9IvmbBH1qgZGzlrt0SaSkhqDhStmfYo6aJmrLvWsa2oaWf/kSXSTqloRuaNIYBqotw6fanop1ZhiDpPcBEaG0FT45RajiC3OqkSiUIJhvDKjRHsNT01Piv4tnjQ9UUrdPg6guohulJpGIVXvWguvwjwESehlhpuoLl+LPikUku7ox3/PLW3+b8d+7Hm0A1eyYv/OCLA/AXfwwNIMmzRb9oPCvHGEEslYH+nrjZv+Q1AcoE/fFcWqjFX5QBJFJ6blnG3fvZlR+tK7Q6pMumGIhmf1GesO2T0AiCAO+0dNPkZuw3lnlNYh3u8uq2EVCMa3FM2PKhDkjMo8qnBk447+oIX8JJexJ43uHLpax24MBYJmiO7Dl/JkTrGzXfD1Ze/fayTNca1e1L3S6wTkkR7Jrw8axFfNydFoHNolz+hrwBGZZ/IARsPXsvdjeuBVjvHmN7CvfbvByIEj1wNHUCYFZmypRHUP/1jI94eM/wAGGjZYG+J/8H9iJCQjRi1/TNrhVNpDe0aB1oj/47ZeuovfNQnuiTcKTCAxcyOpkuAdvJ9dTTRI6i4Y8nOlRI+wqBc25FhXT8L+60uMeG+NqJfwc9D7CnjocJpsXFik05DW1v28wlPEGaUcOyf808uBXcXxmeGM9Gf9mq+yMN9ql5HCrFuy6F4OAA3MD5SbDCzPd/LMv3vEf5xCPLByPiqV1snHTEoEtR8WRndYW1uTkcDDKRa7s+rxVZbzdh010YP1A3LzgVNuUk+Zz8dfIZhWcBDvTivgW6TWlg0PA/FU946CfybfbHjn1BEkJNc3yFhVqMIF4oezTeIwo9Zxch+IYocoDSavpTmh2KafUCP1+bX1d2lCPdQnA2D8S9oVy1zfibXtjkGoz78Giu79KuU+fGSNr012fKa3+bl6GJF1XZlq6u"}}}},"example3":{"summary":"Digital Payment - GooglePay","value":{"clientReferenceInformation":{"code":"mpos_paymentech"},"processingInformation":{"paymentSolution":"012"},"orderInformation":{"billTo":{"country":"US","firstName":"John","lastName":"Deo","phoneNumber":"6504327113","address2":"Desk M3-5573","address1":"901 Metro Center Blvd","postalCode":"94404","locality":"Foster City","company":"Visa","administrativeArea":"CA","email":"test@cybs.com"},"amountDetails":{"totalAmount":"2012","currency":"USD"}},"paymentInformation":{"tokenizedCard":{"expirationYear":"2020","number":"4111111111111111","expirationMonth":"12","transactionType":"1","cryptogram":"EHuWW9PiBkWvqE5juRwDzAUFBAk="}}}},"example4":{"summary":"Digital Payments - ApplePay","value":{"clientReferenceInformation":{"code":"TC_MPOS_Paymentech_2"},"processingInformation":{"paymentSolution":"001"},"orderInformation":{"billTo":{"country":"US","firstName":"John","lastName":"Deo","phoneNumber":"6504327113","address2":"Desk M3-5573","address1":"901 Metro Center Blvd","postalCode":"94404","locality":"Foster City","company":"Visa","administrativeArea":"CA","email":"test@cybs.com"},"amountDetails":{"totalAmount":"100","currency":"USD"}},"paymentInformation":{"tokenizedCard":{"expirationYear":"2031","number":"4111111111111111","expirationMonth":"12","transactionType":"1","cryptogram":"AceY+igABPs3jdwNaDg3MAACAAA="}}}},"example5":{"summary":"Point Of Sale - EMV","value":{"clientReferenceInformation":{"code":"123456"},"pointOfSaleInformation":{"cardPresent":"Y","catLevel":"2","emv":{"fallbackCondition":"swiped","fallback":"Y"},"terminalCapability":"4"},"orderInformation":{"billTo":{"country":"US","lastName":"Doe","address1":"201 S. Division St.","postalCode":"48104-2201","locality":"Ann Arbor","administrativeArea":"MI","firstName":"John","phoneNumber":"999999999","email":"test@cybs.com"},"amountDetails":{"totalAmount":"100.00","currency":"usd"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"372425119311008","securityCode":"123","expirationMonth":"12"},"fluidData":{"value":"%B373235387881007^SMITH/JOHN ^31121019761100 00868000000?;373235387881007=31121019761186800000?"}}}},"example6":{"summary":"Zero Dollar Authorization","value":{"clientReferenceInformation":{"code":"1234567890"},"deviceInformation":{"ipAddress":"66.185.179.2"},"processingInformation":{"capture":"false"},"orderInformation":{"billTo":{"country":"US","firstName":"John","lastName":"Deo","address2":"Desk M3-5573","address1":"901 Metro Center Blvd","postalCode":"88880","locality":"Foster City","administrativeArea":"CA","email":"test@cybs.com"},"amountDetails":{"totalAmount":10,"currency":"USD"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"4111111111111111","securityCode":"123","expirationMonth":"12"}}}},"example7":{"summary":"Level II Data","value":{"clientReferenceInformation":{"code":"TC50171_12"},"processingInformation":{"commerceIndicator":"internet"},"aggregatorInformation":{"subMerchant":{"cardAcceptorId":"1234567890","country":"US","phoneNumber":"650-432-0000","address1":"900 Metro Center","postalCode":"94404-2775","locality":"Foster City","name":"Visa Inc","administrativeArea":"CA","region":"PEN","email":"test@cybs.com"},"name":"V-International","aggregatorId":"123456789"},"orderInformation":{"billTo":{"country":"US","lastName":"Doe","address2":"Address 2","address1":"201 S. Division St.","postalCode":"48104-2201","locality":"Ann Arbor","administrativeArea":"MI","firstName":"John","phoneNumber":"999999999","district":"MI","buildingNumber":"123","company":"Visa","email":"test@cybs.com"},"invoiceDetails":{"purchaseOrderNumber":"LevelII Auth Po"},"amountDetails":{"totalAmount":"112.00","currency":"USD"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"4111111111111111","securityCode":"123","expirationMonth":"12","type":"001"}}}},"example8":{"summary":"Level III Data","value":{"clientReferenceInformation":{"code":"TC50171_14"},"processingInformation":{"commerceIndicator":"internet","purchaseLevel":"3"},"aggregatorInformation":{"subMerchant":{"cardAcceptorId":"1234567890","country":"US","phoneNumber":"650-432-0000","address1":"900 Metro Center","postalCode":"94404-2775","locality":"Foster City","name":"Visa Inc","administrativeArea":"CA","region":"PEN","email":"test@cybs.com"},"name":"V-Internatio","aggregatorId":"123456789"},"orderInformation":{"billTo":{"country":"US","lastName":"Doe","address2":"Address 2","address1":"201 S. Division St.","postalCode":"48104-2201","locality":"Ann Arbor","administrativeArea":"MI","firstName":"John","phoneNumber":"999999999","district":"MI","buildingNumber":"123","company":"Visa","email":"test@cybs.com"},"invoiceDetails":{"purchaseOrderNumber":"LevelIII Auth Po"},"amountDetails":{"totalAmount":"114.00","currency":"USD"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"4111111111111111","securityCode":"123","expirationMonth":"12","type":"001"}}}},"example9":{"summary":"Partial Authorization","value":{"clientReferenceInformation":{"code":"1234567890"},"pointOfSaleInformation":{"cardPresent":"true","catLevel":"6","emv":{"fallbackCondition":"swiped","fallback":"N"},"terminalCapability":"4"},"orderInformation":{"billTo":{"country":"US","firstName":"John","lastName":"Doe","address1":"901 Metro Center Blvd","postalCode":"40500","locality":"Foster City","administrativeArea":"CA","email":"test@cybs.com"},"amountDetails":{"totalAmount":"7012.00","currency":"USD"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"4111111111111111","securityCode":"123","expirationMonth":"12"}}}}}}},"/pts/v2/payments/{id}/reversals":{"post":{"summary":"Process an Authorization Reversal","description":"Include the payment ID in the POST request to reverse the payment amount.","tags":["reversal"],"operationId":"authReversal","parameters":[{"name":"id","in":"path","description":"The payment ID returned from a previous payment request.","required":true,"type":"string"},{"name":"authReversalRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"comments":{"type":"string","description":"Comments"}}},"reversalInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}},"reason":{"type":"string","maxLength":3,"description":"Reason for the authorization reversal. Possible value:\n\n - 34: Suspected fraud\n\nCyberSource ignores this field for processors that do not support this value.\n"}}},"processingInformation":{"type":"object","properties":{"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"reconciliationId":{"type":"string","maxLength":60,"description":"Please check with Cybersource customer support to see if your merchant account is configured correctly so you\ncan include this field in your request.\n* For Payouts: max length for FDCCompass is String (22).\n"},"linkId":{"type":"string","maxLength":26,"description":"Value that links the current payment request to the original request. Set this value\nto the ID that was returned in the reply message from the original payment request.\n\nThis value is used for:\n\n - Partial authorizations.\n - Split shipments.\n"},"reportGroup":{"type":"string","maxLength":25,"description":"Attribute that lets you define custom grouping for your processor reports. This field is supported only for\n**Litle**.\n"},"visaCheckoutId":{"type":"string","maxLength":48,"description":"Identifier for the **Visa Checkout** order. Visa Checkout provides a unique order ID for every transaction in\nthe Visa Checkout **callID** field.\n"},"issuer":{"type":"object","properties":{"discretionaryData":{"type":"string","maxLength":255,"description":"Data defined by the issuer. The value for this reply field will probably be the same as the value that you\nsubmitted in the authorization request, but it is possible for the processor, issuer, or acquirer to modify\nthe value.\n\nThis field is supported only for Visa transactions on **CyberSource through VisaNet**.\n"}}}}},"orderInformation":{"type":"object","properties":{"lineItems":{"type":"array","items":{"type":"object","properties":{"quantity":{"type":"number","minimum":1,"maximum":9999999999,"description":"For a payment or capture, this field is required when _productCode_ is not **default** or one of the values\nrelated to shipping and handling.\n","default":1},"unitPrice":{"type":"string","maxLength":15,"description":"Per-item price of the product. This value cannot be negative. You can include a decimal point (.), but you\ncannot include any other special characters. CyberSource truncates the amount to the correct number of decimal\nplaces.\n\nFor processor-specific information, see the amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}}}}},"pointOfSaleInformation":{"type":"object","properties":{"emv":{"type":"object","properties":{"tags":{"type":"string","maxLength":1998,"description":"EMV data that is transmitted from the chip card to the issuer, and from the issuer to the chip card. The EMV\ndata is in the tag-length-value format and includes chip card tags, terminal tags, and transaction detail tags.\n\n`Important` The following tags contain sensitive information and **must not** be included in this field:\n\n - **56**: Track 1 equivalent data\n - **57**: Track 2 equivalent data\n - **5A**: Application PAN\n - **5F20**: Cardholder name\n - **5F24**: Application expiration date (This sensitivity has been relaxed for cmcic, amexdirect, fdiglobal, opdfde, six)\n - **99**: Transaction PIN\n - **9F0B**: Cardholder name (extended)\n - **9F1F**: Track 1 discretionary data\n - **9F20**: Track 2 discretionary data\n\nFor captures, this field is required for contact EMV transactions. Otherwise, it is optional.\n\nFor credits, this field is required for contact EMV stand-alone credits and contactless EMV stand-alone credits.\nOtherwise, it is optional.\n\n`Important` For contact EMV captures, contact EMV stand-alone credits, and contactless EMV stand-alone credits,\nyou must include the following tags in this field. For all other types of EMV transactions, the following tags\nare optional.\n\n - **95**: Terminal verification results\n - **9F10**: Issuer application data\n - **9F26**: Application cryptogram\n"}}}}}},"example":{"clientReferenceInformation":{"code":"TC50171_3"},"reversalInformation":{"reason":"testing","amountDetails":{"totalAmount":"102.21"}}}}}],"responses":{"201":{"description":"Successful response.","schema":{"type":"object","title":"ptsV2PaymentsReversalsPost201Response","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["REVERSED"]},"reconciliationId":{"type":"string","maxLength":60,"description":"The reconciliation id for the submitted transaction. This value is not returned for all processors.\n"},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"reversalAmountDetails":{"type":"object","properties":{"reversedAmount":{"type":"string","maxLength":15,"description":"Total reversed amount."},"originalTransactionAmount":{"type":"string","maxLength":15,"description":"Amount of the original transaction."},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}},"processorInformation":{"type":"object","properties":{"transactionId":{"type":"string","maxLength":18,"description":"Processor transaction ID.\n\nThis value identifies the transaction on a host system. This value is supported only for Moneris. It contains\nthis information:\n\n - Terminal used to process the transaction\n - Shift during which the transaction took place\n - Batch number\n - Transaction number within the batch\n\nYou must store this value. If you give the customer a receipt, display this value on the receipt.\n\nExample For the value 66012345001069003:\n\n - Terminal ID = 66012345\n - Shift number = 001\n - Batch number = 069\n - Transaction number = 003\n"},"responseCode":{"type":"string","maxLength":10,"description":"For most processors, this is the error message sent directly from the bank. Returned only when the processor\nreturns this value.\n\nImportant Do not use this field to evaluate the result of the authorization.\n"},"responseCategoryCode":{"type":"string","maxLength":32,"description":"Processor-defined response category code. The associated detail error code is in the auth_auth_response\nfield or the auth_reversal_auth_ response field depending on which service you requested.\n\nThis field is supported only for:\n\n - Japanese issuers\n - Domestic transactions in Japan\n - Comercio Latino\u2014processor transaction ID required for troubleshooting\n\n**Maximum length for processors**:\n\n - Comercio Latino: 32\n - All other processors: 3\n"},"forwardedAcquirerCode":{"type":"string","maxLength":32,"description":"Name of the Japanese acquirer that processed the transaction. Returned only for CCS (CAFIS) and JCN Gateway.\nPlease contact the CyberSource Japan Support Group for more information.\n"},"masterCardServiceCode":{"type":"string","maxLength":2,"description":"Mastercard service that was used for the transaction. Mastercard provides this value to CyberSource.\n\nPossible value:\n - 53: Mastercard card-on-file token service\n"},"masterCardServiceReplyCode":{"type":"string","maxLength":1,"description":"Result of the Mastercard card-on-file token service. Mastercard provides this value to CyberSource.\n\nPossible values:\n\n - **C**: Service completed successfully.\n - **F**: One of the following:\n - Incorrect Mastercard POS entry mode. The Mastercard POS entry mode should be 81 for an authorization or\n authorization reversal.\n - Incorrect Mastercard POS entry mode. The Mastercard POS entry mode should be 01 for a tokenized request.\n - Token requestor ID is missing or formatted incorrectly.\n - **I**: One of the following:\n - Invalid token requestor ID.\n - Suspended or deactivated token.\n - Invalid token (not in mapping table).\n - **T**: Invalid combination of token requestor ID and token.\n - **U**: Expired token.\n - **W**: Primary account number (PAN) listed in electronic warning bulletin.\n\nNote This field is returned only for **CyberSource through VisaNet**.\n"}}},"authorizationInformation":{"type":"object","properties":{"approvalCode":{"type":"string","maxLength":6,"description":"The authorization code returned by the processor."},"reasonCode":{"type":"string","maxLength":50,"description":"Reply flag for the original transaction."}}},"pointOfSaleInformation":{"type":"object","properties":{"emv":{"type":"object","properties":{"tags":{"type":"string","maxLength":1998,"description":"EMV data that is transmitted from the chip card to the issuer, and from the issuer to the chip card. The EMV\ndata is in the tag-length-value format and includes chip card tags, terminal tags, and transaction detail tags.\n\n`Important` The following tags contain sensitive information and **must not** be included in this field:\n\n - **56**: Track 1 equivalent data\n - **57**: Track 2 equivalent data\n - **5A**: Application PAN\n - **5F20**: Cardholder name\n - **5F24**: Application expiration date (This sensitivity has been relaxed for cmcic, amexdirect, fdiglobal, opdfde, six)\n - **99**: Transaction PIN\n - **9F0B**: Cardholder name (extended)\n - **9F1F**: Track 1 discretionary data\n - **9F20**: Track 2 discretionary data\n\nFor captures, this field is required for contact EMV transactions. Otherwise, it is optional.\n\nFor credits, this field is required for contact EMV stand-alone credits and contactless EMV stand-alone credits.\nOtherwise, it is optional.\n\n`Important` For contact EMV captures, contact EMV stand-alone credits, and contactless EMV stand-alone credits,\nyou must include the following tags in this field. For all other types of EMV transactions, the following tags\nare optional.\n\n - **95**: Terminal verification results\n - **9F10**: Issuer application data\n - **9F26**: Application cryptogram\n"}}}}}},"example":{"_links":{"self":{"href":"/pts/v2/reversals/4963015523026180001545","method":"GET"}},"id":"4963015523026180001545","submitTimeUtc":"2017-06-01T071912Z","status":"200","statusInformation":{"reason":"SUCCESS","message":"Successful transaction."},"clientReferenceInformation":{"code":"TC50171_3"},"orderInformation":{"amountDetails":{"currency":"USD"}},"processorInformation":{"responseCode":"100"},"reversalAmountDetails":{"reversedAmount":"102.21","currency":"USD"}}}},"400":{"description":"Invalid request.","schema":{"type":"object","title":"ptsV2PaymentsReversalsPost400Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_MERCHANT_CONFIGURATION","AUTH_ALREADY_REVERSED","MISSING_AUTH","TRANSACTION_ALREADY_REVERSED_OR_SETTLED"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"type":"object","title":"ptsV2PaymentsReversalsPost502Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Process an Authorization Reversal","value":{"clientReferenceInformation":{"code":"TC50171_3"},"reversalInformation":{"reason":"testing","amountDetails":{"totalAmount":"102.21"}}}}}}},"/pts/v2/payments/{id}/captures":{"post":{"summary":"Capture a Payment","description":"Include the payment ID in the POST request to capture the payment amount.","tags":["capture"],"operationId":"capturePayment","parameters":[{"name":"capturePaymentRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"transactionId":{"type":"string","description":"Identifier that you assign to the transaction. See \"Merchant-Initiated Reversals and Voids,\" page 176\n"},"comments":{"type":"string","description":"Comments"}}},"processingInformation":{"type":"object","properties":{"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"reconciliationId":{"type":"string","maxLength":60,"description":"Please check with Cybersource customer support to see if your merchant account is configured correctly so you\ncan include this field in your request.\n* For Payouts: max length for FDCCompass is String (22).\n"},"linkId":{"type":"string","maxLength":26,"description":"Value that links the current payment request to the original request. Set this value\nto the ID that was returned in the reply message from the original payment request.\n\nThis value is used for:\n\n - Partial authorizations.\n - Split shipments.\n"},"reportGroup":{"type":"string","maxLength":25,"description":"Attribute that lets you define custom grouping for your processor reports. This field is supported only for\n**Litle**.\n"},"visaCheckoutId":{"type":"string","maxLength":48,"description":"Identifier for the **Visa Checkout** order. Visa Checkout provides a unique order ID for every transaction in\nthe Visa Checkout **callID** field.\n"},"purchaseLevel":{"type":"string","maxLength":1,"description":"Set this field to 3 to indicate that the request includes Level III data."},"issuer":{"type":"object","properties":{"discretionaryData":{"type":"string","maxLength":255,"description":"Data defined by the issuer. The value for this reply field will probably be the same as the value that you\nsubmitted in the authorization request, but it is possible for the processor, issuer, or acquirer to modify\nthe value.\n\nThis field is supported only for Visa transactions on **CyberSource through VisaNet**.\n"}}},"authorizationOptions":{"type":"object","properties":{"authType":{"type":"string","maxLength":15,"description":"Authorization type. Possible values:\n\n - **AUTOCAPTURE**: automatic capture.\n - **STANDARDCAPTURE**: standard capture.\n - **VERBAL**: forced capture. Include it in the payment request for a forced capture. Include it in the capture\n request for a verbal payment.\n\nFor processor-specific information, see the auth_type field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"verbalAuthCode":{"type":"string","maxLength":7,"description":"Authorization code.\n\n**Forced Capture**\n\nUse this field to send the authorization code you received from a payment that you authorized\noutside the CyberSource system.\n\n**Verbal Authorization**\n\nUse this field in CAPTURE API to send the verbally received authorization code.\n\nFor processor-specific information, see the auth_code field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"verbalAuthTransactionId":{"type":"string","maxLength":15,"description":"Transaction ID (TID)."}}},"captureOptions":{"type":"object","properties":{"captureSequenceNumber":{"type":"number","minimum":1,"maximum":99,"description":"Capture number when requesting multiple partial captures for one payment.\nUsed along with _totalCaptureCount_ to track which capture is being processed.\n\nFor example, the second of five captures would be passed to CyberSource as:\n - _captureSequenceNumber_ = 2, and\n - _totalCaptureCount_ = 5\n"},"totalCaptureCount":{"type":"number","minimum":1,"maximum":99,"description":"Total number of captures when requesting multiple partial captures for one payment.\nUsed along with _captureSequenceNumber_ which capture is being processed.\n\nFor example, the second of five captures would be passed to CyberSource as:\n - _captureSequenceNumber_ = 2, and\n - _totalCaptureCount_ = 5\n"}}}}},"paymentInformation":{"type":"object","properties":{"customer":{"type":"object","properties":{"customerId":{"type":"string","maxLength":26,"description":"Unique identifier for the customer's card and billing information."}}}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"},"discountAmount":{"type":"string","maxLength":15,"description":"Total discount amount applied to the order.\n\nFor processor-specific information, see the order_discount_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"dutyAmount":{"type":"string","maxLength":15,"description":"Total charges for any import or export duties included in the order.\n\nFor processor-specific information, see the duty_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAmount":{"type":"string","maxLength":12,"description":"Total tax amount for all the items in the order.\n\nFor processor-specific information, see the total_tax_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"nationalTaxIncluded":{"type":"string","maxLength":1,"description":"Flag that indicates whether a national tax is included in the order total.\n\nPossible values:\n\n - **0**: national tax not included\n - **1**: national tax included\n\nFor processor-specific information, see the national_tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag that indicates how the merchant manages discounts.\n\nPossible values:\n\n - **0**: no invoice level discount included\n - **1**: tax calculated on the postdiscount invoice total\n - **2**: tax calculated on the prediscount invoice total\n\nFor processor-specific information, see the order_discount_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedLevel":{"type":"string","maxLength":1,"description":"Flag that indicates how you calculate tax.\n\nPossible values:\n\n - **0**: net prices with tax calculated at line item level\n - **1**: net prices with tax calculated at invoice level\n - **2**: gross prices with tax provided at line item level\n - **3**: gross prices with tax provided at invoice level\n - **4**: no tax applies on the invoice for the transaction\n\nFor processor-specific information, see the tax_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxTypeCode":{"type":"string","maxLength":3,"description":"For tax amounts that can be categorized as one tax type.\n\nThis field contains the tax type code that corresponds to the entry in the _lineItems.taxAmount_ field.\n\nPossible values:\n\n - **056**: sales tax (U.S only)\n - **TX~**: all taxes (Canada only) Note ~ = space.\n\nFor processor-specific information, see the total_tax_type_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"freightAmount":{"type":"string","maxLength":13,"description":"Total freight or shipping and handling charges for the order. When you include this field in your request, you\nmust also include the **totalAmount** field.\n\nFor processor-specific information, see the freight_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"foreignAmount":{"type":"string","maxLength":15,"description":"Converted amount returned by the DCC service.\n\nFor processor-specific information, see the foreign_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"foreignCurrency":{"type":"string","maxLength":5,"description":"Billing currency returned by the DCC service.\n\nFor processor-specific information, see the foreign_currency field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRate":{"type":"string","maxLength":13,"description":"Exchange rate returned by the DCC service. Includes a decimal point and a maximum of 4 decimal places.\n\nFor processor-specific information, see the exchange_rate field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRateTimeStamp":{"type":"string","maxLength":14,"description":"Time stamp for the exchange rate. This value is returned by the DCC service.\n\nFormat: `YYYYMMDD~HH:MM` where ~ denotes a space.\n\nFor processor-specific information, see the exchange_rate_timestamp field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amexAdditionalAmounts":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","maxLength":3,"description":"Additional amount type. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount_type field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amount":{"type":"string","maxLength":12,"description":"Additional amount. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}}},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"company":{"type":"string","maxLength":60,"description":"Name of the customer\u2019s company.\n\nFor processor-specific information, see the company_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the billing street address as it appears on the credit card issuer\u2019s records.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address1 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address2":{"type":"string","maxLength":60,"description":"Additional address information.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address2 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":50,"description":"City of the billing address.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_city field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the billing address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_state field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the billing address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_zip field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"email":{"type":"string","maxLength":255,"description":"Customer's email address, including the full domain name.\n\nFor processor-specific information, see the customer_email field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"shipTo":{"type":"object","properties":{"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the shipping address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n"},"country":{"type":"string","maxLength":2,"description":"Country of the shipping address. Use the two character ISO Standard Country Codes."},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the shipping address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n"}}},"lineItems":{"type":"array","items":{"type":"object","properties":{"productCode":{"type":"string","maxLength":255,"description":"Type of product. This value is used to determine the category that the product is in: electronic, handling,\nphysical, service, or shipping. The default value is **default**.\n\nFor a payment, when you set this field to a value other than default or any of the values related to\nshipping and handling, below fields _quantity_, _productName_, and _productSKU_ are required.\n"},"productName":{"type":"string","maxLength":255,"description":"For PAYMENT and CAPTURE API, this field is required when above _productCode_ is not **default** or one of the\nvalues related to shipping and handling.\n"},"productSku":{"type":"string","maxLength":255,"description":"Identification code for the product. For PAYMENT and CAPTURE API, this field is required when above\n_productCode_ is not **default** or one of the values related to shipping and/or handling.\n"},"quantity":{"type":"number","minimum":1,"maximum":9999999999,"description":"For a payment or capture, this field is required when _productCode_ is not **default** or one of the values\nrelated to shipping and handling.\n","default":1},"unitPrice":{"type":"string","maxLength":15,"description":"Per-item price of the product. This value cannot be negative. You can include a decimal point (.), but you\ncannot include any other special characters. CyberSource truncates the amount to the correct number of decimal\nplaces.\n\nFor processor-specific information, see the amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"unitOfMeasure":{"type":"string","maxLength":12,"description":"Unit of measure, or unit of measure code, for the item.\n"},"totalAmount":{"type":"string","maxLength":13,"description":"Total amount for the item. Normally calculated as the unit price x quantity.\n"},"taxAmount":{"type":"string","maxLength":15,"description":"Total tax to apply to the product. This value cannot be negative. The tax amount and the offer amount must\nbe in the same currency. The tax amount field is additive.\n\nThe following example uses a two-exponent currency such as USD:\n\n 1. You include each line item in your request.\n ..- 1st line item has amount=10.00, quantity=1, and taxAmount=0.80\n ..- 2nd line item has amount=20.00, quantity=1, and taxAmount=1.60\n 2. The total amount authorized will be 32.40, not 30.00 with 2.40 of tax included.\n\nThis field is frequently used for Level II and Level III transactions.\n"},"taxRate":{"type":"string","maxLength":7,"description":"Tax rate applied to the item. See \"Numbered Elements,\" page 14.\n\nVisa: Valid range is 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated).\n\nMastercard: Valid range is 0.00001 to 0.99999 (0.001% to 99.999%).\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag to indicate how you handle discount at the line item level.\n\n - 0: no line level discount provided\n - 1: tax was calculated on the post-discount line item total\n - 2: tax was calculated on the pre-discount line item total\n\n`Note` Visa will inset 0 (zero) if an invalid value is included in this field.\n\nThis field relates to the value in the _lineItems[].discountAmount_ field.\n"},"taxStatusIndicator":{"type":"string","maxLength":1,"description":"Flag to indicate whether tax is exempted or not included.\n\n - 0: tax not included\n - 1: tax included\n - 2: transaction is not subject to tax\n"},"taxTypeCode":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"amountIncludesTax":{"type":"boolean","description":"Flag that indicates whether the tax amount is included in the Line Item Total.\n","enum":[true,false]},"typeOfSupply":{"type":"string","maxLength":2,"description":"Flag to indicate whether the purchase is categorized as goods or services.\nPossible values:\n\n - 00: goods\n - 01: services\n"},"commodityCode":{"type":"string","maxLength":15,"description":"Commodity code or International description code used to classify the item. Contact your acquirer for a list of\ncodes.\n"},"discountAmount":{"type":"string","maxLength":13,"description":"Discount applied to the item."},"discountApplied":{"type":"boolean","description":"Flag that indicates whether the amount is discounted.\n\nIf you do not provide a value but you set Discount Amount to a value greater than zero, then CyberSource sets\nthis field to **true**.\n","enum":[true,false]},"discountRate":{"type":"string","maxLength":6,"description":"Rate the item is discounted. Maximum of 2 decimal places.\n\nExample 5.25 (=5.25%)\n"},"invoiceNumber":{"type":"string","maxLength":23,"description":"Field to support an invoice number for a transaction. You must specify the number of line items that will\ninclude an invoice number. By default, the first line item will include an invoice number field. The invoice\nnumber field can be included for up to 10 line items.\n"},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}},"fulfillmentType":{"type":"string","description":"TODO"}}}},"invoiceDetails":{"type":"object","properties":{"purchaseOrderNumber":{"type":"string","maxLength":25,"description":"Value used by your customer to identify the order. This value is typically a purchase order number. CyberSource\nrecommends that you do not populate the field with all zeros or nines.\n\nFor processor-specific information, see the user_po field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseOrderDate":{"type":"string","maxLength":10,"description":"Date the order was processed. `Format: YYYY-MM-DD`.\n\nFor processor-specific information, see the purchaser_order_date field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseContactName":{"type":"string","maxLength":36,"description":"The name of the individual or the company contacted for company authorized purchases.\n\nFor processor-specific information, see the authorized_contact_name field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxable":{"type":"boolean","description":"Flag that indicates whether an order is taxable. This value must be true if the sum of all _lineItems[].taxAmount_ values > 0.\n\nIf you do not include any _lineItems[].taxAmount_ values in your request, CyberSource does not include\n_invoiceDetails.taxable_ in the data it sends to the processor.\n\nFor processor-specific information, see the tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]},"vatInvoiceReferenceNumber":{"type":"string","maxLength":15,"description":"VAT invoice number associated with the transaction.\n\nFor processor-specific information, see the vat_invoice_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"commodityCode":{"type":"string","maxLength":4,"description":"International description code of the overall order\u2019s goods or services or the Categorizes purchases for VAT\nreporting. Contact your acquirer for a list of codes.\n\nFor processor-specific information, see the summary_commodity_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"transactionAdviceAddendum":{"type":"array","items":{"type":"object","properties":{"data":{"type":"string","maxLength":40,"description":"Four Transaction Advice Addendum (TAA) fields. These fields are used to display descriptive information\nabout a transaction on the customer\u2019s American Express card statement. When you send TAA fields, start\nwith amexdata_taa1, then ...taa2, and so on. Skipping a TAA field causes subsequent TAA fields to be\nignored.\n\nTo use these fields, contact CyberSource Customer Support to have your account enabled for this feature.\n"}}}}}},"shippingDetails":{"type":"object","properties":{"shipFromPostalCode":{"type":"string","maxLength":10,"description":"Postal code for the address from which the goods are shipped, which is used to establish nexus. The default is\nthe postal code associated with your CyberSource account.\n\nThe postal code must consist of 5 to 9 digits. When the billing country is the U.S., the 9-digit postal code\nmust follow this format:\n\n`[5 digits][dash][4 digits]`\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n\n`[alpha][numeric][alpha][space] [numeric][alpha][numeric]`\n\nExample A1B 2C3\n\nThis field is frequently used for Level II and Level III transactions.\n"}}}}},"buyerInformation":{"type":"object","properties":{"merchantCustomerId":{"type":"string","maxLength":100,"description":"Your identifier for the customer.\n\nFor processor-specific information, see the customer_account_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":20,"description":"Customer\u2019s government-assigned tax identification number.\n\nFor processor-specific information, see the purchaser_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"}}},"deviceInformation":{"type":"object","properties":{"hostName":{"type":"string","maxLength":60,"description":"DNS resolved hostname from above _ipAddress_."},"ipAddress":{"type":"string","maxLength":15,"description":"IP address of the customer."},"userAgent":{"type":"string","maxLength":40,"description":"Customer\u2019s browser as identified from the HTTP header data. For example, Mozilla is the value that identifies\nthe Netscape browser.\n"}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"name":{"type":"string","maxLength":23,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\nFor Payouts:\n* Paymentech (22)\n"},"alternateName":{"type":"string","maxLength":13,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"contact":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n* FDCCompass (13)\n* Paymentech (13)\n"},"address1":{"type":"string","maxLength":60,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":13,"description":"Merchant City. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":3,"description":"Merchant State. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"cardAcceptorReferenceNumber":{"type":"string","maxLength":25,"description":"Reference number that facilitates card acceptor/corporation communication and record keeping.\n\nFor processor-specific information, see the card_acceptor_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"categoryCode":{"type":"integer","maximum":9999,"description":"Four-digit number that the payment card industry uses to classify merchants into market segments. Visa assigned\none or more of these values to your business when you started accepting Visa cards.\n\nIf you do not include this field in your request, CyberSource uses the value in your CyberSource account.\n\nFor processor-specific information, see the merchant_category_code field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":21,"description":"Your government-assigned tax identification number.\n\nFor CtV processors, the maximum length is 20.\n\nFor other processor-specific information, see the merchant_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"}}},"aggregatorInformation":{"type":"object","properties":{"aggregatorId":{"type":"string","maxLength":20,"description":"Value that identifies you as a payment aggregator. Get this value from the\nprocessor.\n\nFor processor-specific information, see the aggregator_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"name":{"type":"string","maxLength":37,"description":"Your payment aggregator business name.\n\nFor processor-specific information, see the aggregator_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"subMerchant":{"type":"object","properties":{"name":{"type":"string","maxLength":37,"description":"Sub-merchant\u2019s business name."},"address1":{"type":"string","maxLength":38,"description":"First line of the sub-merchant\u2019s street address."},"locality":{"type":"string","maxLength":21,"description":"Sub-merchant\u2019s city."},"administrativeArea":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s state or province. Use the State, Province, and Territory Codes for the United States and Canada.\n"},"postalCode":{"type":"string","maxLength":15,"description":"Partial postal code for the sub-merchant\u2019s address."},"country":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s country. Use the two-character ISO Standard Country Codes."},"email":{"type":"string","maxLength":40,"description":"Sub-merchant\u2019s email address.\n\n**Maximum length for processors**\n\n - American Express Direct: 40\n - CyberSource through VisaNet: 40\n - FDC Compass: 40\n - FDC Nashville Global: 19\n"},"phoneNumber":{"type":"string","maxLength":20,"description":"Sub-merchant\u2019s telephone number.\n\n**Maximum length for procesors**\n\n - American Express Direct: 20\n - CyberSource through VisaNet: 20\n - FDC Compass: 13\n - FDC Nashville Global: 10\n"}}}}},"pointOfSaleInformation":{"type":"object","properties":{"emv":{"type":"object","properties":{"tags":{"type":"string","maxLength":1998,"description":"EMV data that is transmitted from the chip card to the issuer, and from the issuer to the chip card. The EMV\ndata is in the tag-length-value format and includes chip card tags, terminal tags, and transaction detail tags.\n\n`Important` The following tags contain sensitive information and **must not** be included in this field:\n\n - **56**: Track 1 equivalent data\n - **57**: Track 2 equivalent data\n - **5A**: Application PAN\n - **5F20**: Cardholder name\n - **5F24**: Application expiration date (This sensitivity has been relaxed for cmcic, amexdirect, fdiglobal, opdfde, six)\n - **99**: Transaction PIN\n - **9F0B**: Cardholder name (extended)\n - **9F1F**: Track 1 discretionary data\n - **9F20**: Track 2 discretionary data\n\nFor captures, this field is required for contact EMV transactions. Otherwise, it is optional.\n\nFor credits, this field is required for contact EMV stand-alone credits and contactless EMV stand-alone credits.\nOtherwise, it is optional.\n\n`Important` For contact EMV captures, contact EMV stand-alone credits, and contactless EMV stand-alone credits,\nyou must include the following tags in this field. For all other types of EMV transactions, the following tags\nare optional.\n\n - **95**: Terminal verification results\n - **9F10**: Issuer application data\n - **9F26**: Application cryptogram\n"},"fallback":{"type":"boolean","maxLength":5,"description":"Indicates whether a fallback method was used to enter credit card information into the POS terminal. When a\ntechnical problem prevents a successful exchange of information between a chip card and a chip-capable terminal:\n\n 1. Swipe the card or key the credit card information into the POS terminal.\n 2. Use the pos_entry_mode field to indicate whether the information was swiped or keyed.\n\nThis field is supported only on **Chase Paymentech Solutions** and **GPN**.\n","enum":[true,false],"default":false}}},"amexCapnData":{"type":"string","maxLength":12,"description":"Point-of-sale details for the transaction. This value is returned only for **American Express Direct**.\nCyberSource generates this value, which consists of a series of codes that identify terminal capability,\nsecurity data, and specific conditions present at the time the transaction occurred. To comply with the CAPN\nrequirements, this value must be included in all subsequent follow-on requests, such as captures and follow-on\ncredits.\n\nWhen you perform authorizations, captures, and credits through CyberSource, CyberSource passes this value from\nthe authorization service to the subsequent services for you. However, when you perform authorizations through\nCyberSource and perform subsequent services through other financial institutions, you must ensure that your\nrequests for captures and credits include this value.\n"}}},"merchantDefinedInformation":{"type":"array","description":"Description of this field is not available.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":50,"description":"Description of this field is not available."},"value":{"type":"string","maxLength":255,"description":"Description of this field is not available."}}}}},"example":{"clientReferenceInformation":{"code":"TC50171_3"},"orderInformation":{"amountDetails":{"totalAmount":"102.21","currency":"USD"}}}}},{"name":"id","in":"path","description":"The payment ID returned from a previous payment request. This ID links the capture to the payment.\n","required":true,"type":"string"}],"responses":{"201":{"description":"Successful response.","schema":{"type":"object","title":"ptsV2PaymentsCapturesPost201Response","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}},"void":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}},"refund":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["PENDING"]},"reconciliationId":{"type":"string","maxLength":60,"description":"The reconciliation id for the submitted transaction. This value is not returned for all processors.\n"},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"processorInformation":{"type":"object","properties":{"transactionId":{"type":"string","maxLength":18,"description":"Processor transaction ID.\n\nThis value identifies the transaction on a host system. This value is supported only for Moneris. It contains\nthis information:\n\n - Terminal used to process the transaction\n - Shift during which the transaction took place\n - Batch number\n - Transaction number within the batch\n\nYou must store this value. If you give the customer a receipt, display this value on the receipt.\n\nExample For the value 66012345001069003:\n\n - Terminal ID = 66012345\n - Shift number = 001\n - Batch number = 069\n - Transaction number = 003\n"}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":15,"description":"Amount you requested for the capture.\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}},"invoiceDetails":{"type":"object","properties":{"level3TransmissionStatus":{"type":"boolean","description":"Indicates whether CyberSource sent the Level III information to the processor. The possible values are:\n\nIf your account is not enabled for Level III data or if you did not include the purchasing level field in your\nrequest, CyberSource does not include the Level III data in the request sent to the processor.\n\nFor processor-specific information, see the bill_purchasing_level3_enabled field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]}}}}}},"example":{"_links":{"self":{"href":"/pts/v2/captures/4963014519526177701545","method":"GET"},"refund":{"href":"/pts/v2/captures/4963014519526177701545/refunds","method":"POST"},"void":{"href":"/pts/v2/captures/4963014519526177701545/voids","method":"POST"}},"id":"4963014519526177701545","submitTimeUtc":"2017-06-01T071731Z","status":"200","reconciliationId":"39570715X3E1LBQA","statusInformation":{"reason":"SUCCESS","message":"Successful transaction."},"clientReferenceInformation":{"code":"TC50171_3"},"orderInformation":{"amountDetails":{"totalAmount":"102.21","currency":"USD"}}}}},"400":{"description":"Invalid request.","schema":{"type":"object","title":"ptsV2PaymentsCapturesPost400Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_MERCHANT_CONFIGURATION","EXCEEDS_AUTH_AMOUNT","AUTH_ALREADY_REVERSED","TRANSACTION_ALREADY_SETTLED","MISSING_AUTH","TRANSACTION_ALREADY_REVERSED_OR_SETTLED"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"type":"object","title":"ptsV2PaymentsCapturesPost502Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Capture a Payment","value":{"clientReferenceInformation":{"code":"TC50171_3"},"orderInformation":{"amountDetails":{"totalAmount":"102.21","currency":"USD"}}}}}}},"/pts/v2/payments/{id}/refunds":{"post":{"summary":"Refund a Payment","description":"Include the payment ID in the POST request to refund the payment amount.\n","tags":["refund"],"operationId":"refundPayment","parameters":[{"name":"refundPaymentRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"transactionId":{"type":"string","description":"Identifier that you assign to the transaction. See \"Merchant-Initiated Reversals and Voids,\" page 176\n"},"comments":{"type":"string","description":"Comments"}}},"processingInformation":{"type":"object","properties":{"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"reconciliationId":{"type":"string","maxLength":60,"description":"Please check with Cybersource customer support to see if your merchant account is configured correctly so you\ncan include this field in your request.\n* For Payouts: max length for FDCCompass is String (22).\n"},"linkId":{"type":"string","maxLength":26,"description":"Value that links the current payment request to the original request. Set this value\nto the ID that was returned in the reply message from the original payment request.\n\nThis value is used for:\n\n - Partial authorizations.\n - Split shipments.\n"},"reportGroup":{"type":"string","maxLength":25,"description":"Attribute that lets you define custom grouping for your processor reports. This field is supported only for\n**Litle**.\n"},"visaCheckoutId":{"type":"string","maxLength":48,"description":"Identifier for the **Visa Checkout** order. Visa Checkout provides a unique order ID for every transaction in\nthe Visa Checkout **callID** field.\n"},"purchaseLevel":{"type":"string","maxLength":1,"description":"Set this field to 3 to indicate that the request includes Level III data."},"recurringOptions":{"type":"object","properties":{"loanPayment":{"type":"boolean","description":"Flag that indicates whether this is a payment towards an existing contractual loan.\n","enum":[true,false],"default":false}}}}},"paymentInformation":{"type":"object","properties":{"card":{"type":"object","properties":{"number":{"type":"string","maxLength":20,"description":"Customer\u2019s credit card number. Encoded Account Numbers when processing encoded account numbers, use this field\nfor the encoded account number.\n\nFor processor-specific information, see the customer_cc_number field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationMonth":{"type":"string","maxLength":2,"description":"Two-digit month in which the credit card expires. `Format: MM`. Possible values: 01 through 12.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 12.\n\nFor processor-specific information, see the customer_cc_expmo field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationYear":{"type":"string","maxLength":4,"description":"Four-digit year in which the credit card expires. `Format: YYYY`.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 2021.\n\nFor processor-specific information, see the customer_cc_expyr field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"},"accountEncoderId":{"type":"string","maxLength":3,"description":"Identifier for the issuing bank that provided the customer\u2019s encoded account number. Contact your processor\nfor the bank\u2019s ID.\n"},"issueNumber":{"type":"string","maxLength":5,"description":"Number of times a Maestro (UK Domestic) card has been issued to the account holder. The card might or might\nnot have an issue number. The number can consist of one or two digits, and the first digit might be a zero.\nWhen you include this value in your request, include exactly what is printed on the card. A value of 2 is\ndifferent than a value of 02. Do not include the field, even with a blank value, if the card is not a\nMaestro (UK Domestic) card.\n\nThe issue number is not required for Maestro (UK Domestic) transactions.\n"},"startMonth":{"type":"string","maxLength":2,"description":"Month of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: MM`. Possible values: 01 through 12.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"},"startYear":{"type":"string","maxLength":4,"description":"Year of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: YYYY`.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"}}}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"},"discountAmount":{"type":"string","maxLength":15,"description":"Total discount amount applied to the order.\n\nFor processor-specific information, see the order_discount_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"dutyAmount":{"type":"string","maxLength":15,"description":"Total charges for any import or export duties included in the order.\n\nFor processor-specific information, see the duty_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAmount":{"type":"string","maxLength":12,"description":"Total tax amount for all the items in the order.\n\nFor processor-specific information, see the total_tax_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"nationalTaxIncluded":{"type":"string","maxLength":1,"description":"Flag that indicates whether a national tax is included in the order total.\n\nPossible values:\n\n - **0**: national tax not included\n - **1**: national tax included\n\nFor processor-specific information, see the national_tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag that indicates how the merchant manages discounts.\n\nPossible values:\n\n - **0**: no invoice level discount included\n - **1**: tax calculated on the postdiscount invoice total\n - **2**: tax calculated on the prediscount invoice total\n\nFor processor-specific information, see the order_discount_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedLevel":{"type":"string","maxLength":1,"description":"Flag that indicates how you calculate tax.\n\nPossible values:\n\n - **0**: net prices with tax calculated at line item level\n - **1**: net prices with tax calculated at invoice level\n - **2**: gross prices with tax provided at line item level\n - **3**: gross prices with tax provided at invoice level\n - **4**: no tax applies on the invoice for the transaction\n\nFor processor-specific information, see the tax_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxTypeCode":{"type":"string","maxLength":3,"description":"For tax amounts that can be categorized as one tax type.\n\nThis field contains the tax type code that corresponds to the entry in the _lineItems.taxAmount_ field.\n\nPossible values:\n\n - **056**: sales tax (U.S only)\n - **TX~**: all taxes (Canada only) Note ~ = space.\n\nFor processor-specific information, see the total_tax_type_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"freightAmount":{"type":"string","maxLength":13,"description":"Total freight or shipping and handling charges for the order. When you include this field in your request, you\nmust also include the **totalAmount** field.\n\nFor processor-specific information, see the freight_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"foreignAmount":{"type":"string","maxLength":15,"description":"Converted amount returned by the DCC service.\n\nFor processor-specific information, see the foreign_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"foreignCurrency":{"type":"string","maxLength":5,"description":"Billing currency returned by the DCC service.\n\nFor processor-specific information, see the foreign_currency field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRate":{"type":"string","maxLength":13,"description":"Exchange rate returned by the DCC service. Includes a decimal point and a maximum of 4 decimal places.\n\nFor processor-specific information, see the exchange_rate field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRateTimeStamp":{"type":"string","maxLength":14,"description":"Time stamp for the exchange rate. This value is returned by the DCC service.\n\nFormat: `YYYYMMDD~HH:MM` where ~ denotes a space.\n\nFor processor-specific information, see the exchange_rate_timestamp field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amexAdditionalAmounts":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","maxLength":3,"description":"Additional amount type. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount_type field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amount":{"type":"string","maxLength":12,"description":"Additional amount. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}}},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"company":{"type":"string","maxLength":60,"description":"Name of the customer\u2019s company.\n\nFor processor-specific information, see the company_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the billing street address as it appears on the credit card issuer\u2019s records.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address1 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address2":{"type":"string","maxLength":60,"description":"Additional address information.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address2 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":50,"description":"City of the billing address.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_city field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the billing address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_state field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the billing address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_zip field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"email":{"type":"string","maxLength":255,"description":"Customer's email address, including the full domain name.\n\nFor processor-specific information, see the customer_email field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"shipTo":{"type":"object","properties":{"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the shipping address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n"},"country":{"type":"string","maxLength":2,"description":"Country of the shipping address. Use the two character ISO Standard Country Codes."},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the shipping address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n"}}},"lineItems":{"type":"array","items":{"type":"object","properties":{"productCode":{"type":"string","maxLength":255,"description":"Type of product. This value is used to determine the category that the product is in: electronic, handling,\nphysical, service, or shipping. The default value is **default**.\n\nFor a payment, when you set this field to a value other than default or any of the values related to\nshipping and handling, below fields _quantity_, _productName_, and _productSKU_ are required.\n"},"productName":{"type":"string","maxLength":255,"description":"For PAYMENT and CAPTURE API, this field is required when above _productCode_ is not **default** or one of the\nvalues related to shipping and handling.\n"},"productSku":{"type":"string","maxLength":255,"description":"Identification code for the product. For PAYMENT and CAPTURE API, this field is required when above\n_productCode_ is not **default** or one of the values related to shipping and/or handling.\n"},"quantity":{"type":"number","minimum":1,"maximum":9999999999,"description":"For a payment or capture, this field is required when _productCode_ is not **default** or one of the values\nrelated to shipping and handling.\n","default":1},"unitPrice":{"type":"string","maxLength":15,"description":"Per-item price of the product. This value cannot be negative. You can include a decimal point (.), but you\ncannot include any other special characters. CyberSource truncates the amount to the correct number of decimal\nplaces.\n\nFor processor-specific information, see the amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"unitOfMeasure":{"type":"string","maxLength":12,"description":"Unit of measure, or unit of measure code, for the item.\n"},"totalAmount":{"type":"string","maxLength":13,"description":"Total amount for the item. Normally calculated as the unit price x quantity.\n"},"taxAmount":{"type":"string","maxLength":15,"description":"Total tax to apply to the product. This value cannot be negative. The tax amount and the offer amount must\nbe in the same currency. The tax amount field is additive.\n\nThe following example uses a two-exponent currency such as USD:\n\n 1. You include each line item in your request.\n ..- 1st line item has amount=10.00, quantity=1, and taxAmount=0.80\n ..- 2nd line item has amount=20.00, quantity=1, and taxAmount=1.60\n 2. The total amount authorized will be 32.40, not 30.00 with 2.40 of tax included.\n\nThis field is frequently used for Level II and Level III transactions.\n"},"taxRate":{"type":"string","maxLength":7,"description":"Tax rate applied to the item. See \"Numbered Elements,\" page 14.\n\nVisa: Valid range is 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated).\n\nMastercard: Valid range is 0.00001 to 0.99999 (0.001% to 99.999%).\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag to indicate how you handle discount at the line item level.\n\n - 0: no line level discount provided\n - 1: tax was calculated on the post-discount line item total\n - 2: tax was calculated on the pre-discount line item total\n\n`Note` Visa will inset 0 (zero) if an invalid value is included in this field.\n\nThis field relates to the value in the _lineItems[].discountAmount_ field.\n"},"taxStatusIndicator":{"type":"string","maxLength":1,"description":"Flag to indicate whether tax is exempted or not included.\n\n - 0: tax not included\n - 1: tax included\n - 2: transaction is not subject to tax\n"},"taxTypeCode":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"amountIncludesTax":{"type":"boolean","description":"Flag that indicates whether the tax amount is included in the Line Item Total.\n","enum":[true,false]},"typeOfSupply":{"type":"string","maxLength":2,"description":"Flag to indicate whether the purchase is categorized as goods or services.\nPossible values:\n\n - 00: goods\n - 01: services\n"},"commodityCode":{"type":"string","maxLength":15,"description":"Commodity code or International description code used to classify the item. Contact your acquirer for a list of\ncodes.\n"},"discountAmount":{"type":"string","maxLength":13,"description":"Discount applied to the item."},"discountApplied":{"type":"boolean","description":"Flag that indicates whether the amount is discounted.\n\nIf you do not provide a value but you set Discount Amount to a value greater than zero, then CyberSource sets\nthis field to **true**.\n","enum":[true,false]},"discountRate":{"type":"string","maxLength":6,"description":"Rate the item is discounted. Maximum of 2 decimal places.\n\nExample 5.25 (=5.25%)\n"},"invoiceNumber":{"type":"string","maxLength":23,"description":"Field to support an invoice number for a transaction. You must specify the number of line items that will\ninclude an invoice number. By default, the first line item will include an invoice number field. The invoice\nnumber field can be included for up to 10 line items.\n"},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}}}}},"invoiceDetails":{"type":"object","properties":{"purchaseOrderNumber":{"type":"string","maxLength":25,"description":"Value used by your customer to identify the order. This value is typically a purchase order number. CyberSource\nrecommends that you do not populate the field with all zeros or nines.\n\nFor processor-specific information, see the user_po field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseOrderDate":{"type":"string","maxLength":10,"description":"Date the order was processed. `Format: YYYY-MM-DD`.\n\nFor processor-specific information, see the purchaser_order_date field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseContactName":{"type":"string","maxLength":36,"description":"The name of the individual or the company contacted for company authorized purchases.\n\nFor processor-specific information, see the authorized_contact_name field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxable":{"type":"boolean","description":"Flag that indicates whether an order is taxable. This value must be true if the sum of all _lineItems[].taxAmount_ values > 0.\n\nIf you do not include any _lineItems[].taxAmount_ values in your request, CyberSource does not include\n_invoiceDetails.taxable_ in the data it sends to the processor.\n\nFor processor-specific information, see the tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]},"vatInvoiceReferenceNumber":{"type":"string","maxLength":15,"description":"VAT invoice number associated with the transaction.\n\nFor processor-specific information, see the vat_invoice_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"commodityCode":{"type":"string","maxLength":4,"description":"International description code of the overall order\u2019s goods or services or the Categorizes purchases for VAT\nreporting. Contact your acquirer for a list of codes.\n\nFor processor-specific information, see the summary_commodity_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"transactionAdviceAddendum":{"type":"array","items":{"type":"object","properties":{"data":{"type":"string","maxLength":40,"description":"Four Transaction Advice Addendum (TAA) fields. These fields are used to display descriptive information\nabout a transaction on the customer\u2019s American Express card statement. When you send TAA fields, start\nwith amexdata_taa1, then ...taa2, and so on. Skipping a TAA field causes subsequent TAA fields to be\nignored.\n\nTo use these fields, contact CyberSource Customer Support to have your account enabled for this feature.\n"}}}}}},"shippingDetails":{"type":"object","properties":{"shipFromPostalCode":{"type":"string","maxLength":10,"description":"Postal code for the address from which the goods are shipped, which is used to establish nexus. The default is\nthe postal code associated with your CyberSource account.\n\nThe postal code must consist of 5 to 9 digits. When the billing country is the U.S., the 9-digit postal code\nmust follow this format:\n\n`[5 digits][dash][4 digits]`\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n\n`[alpha][numeric][alpha][space] [numeric][alpha][numeric]`\n\nExample A1B 2C3\n\nThis field is frequently used for Level II and Level III transactions.\n"}}}}},"buyerInformation":{"type":"object","properties":{"merchantCustomerId":{"type":"string","maxLength":100,"description":"Your identifier for the customer.\n\nFor processor-specific information, see the customer_account_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":20,"description":"Customer\u2019s government-assigned tax identification number.\n\nFor processor-specific information, see the purchaser_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"}}},"deviceInformation":{"type":"object","properties":{"hostName":{"type":"string","maxLength":60,"description":"DNS resolved hostname from above _ipAddress_."},"ipAddress":{"type":"string","maxLength":15,"description":"IP address of the customer."},"userAgent":{"type":"string","maxLength":40,"description":"Customer\u2019s browser as identified from the HTTP header data. For example, Mozilla is the value that identifies\nthe Netscape browser.\n"}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"name":{"type":"string","maxLength":23,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\nFor Payouts:\n* Paymentech (22)\n"},"alternateName":{"type":"string","maxLength":13,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"contact":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n* FDCCompass (13)\n* Paymentech (13)\n"},"address1":{"type":"string","maxLength":60,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":13,"description":"Merchant City. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":3,"description":"Merchant State. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"categoryCode":{"type":"integer","maximum":9999,"description":"Four-digit number that the payment card industry uses to classify merchants into market segments. Visa assigned\none or more of these values to your business when you started accepting Visa cards.\n\nIf you do not include this field in your request, CyberSource uses the value in your CyberSource account.\n\nFor processor-specific information, see the merchant_category_code field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":21,"description":"Your government-assigned tax identification number.\n\nFor CtV processors, the maximum length is 20.\n\nFor other processor-specific information, see the merchant_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"cardAcceptorReferenceNumber":{"type":"string","maxLength":25,"description":"Reference number that facilitates card acceptor/corporation communication and record keeping.\n\nFor processor-specific information, see the card_acceptor_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"}}},"aggregatorInformation":{"type":"object","properties":{"aggregatorId":{"type":"string","maxLength":20,"description":"Value that identifies you as a payment aggregator. Get this value from the\nprocessor.\n\nFor processor-specific information, see the aggregator_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"name":{"type":"string","maxLength":37,"description":"Your payment aggregator business name.\n\nFor processor-specific information, see the aggregator_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"subMerchant":{"type":"object","properties":{"name":{"type":"string","maxLength":37,"description":"Sub-merchant\u2019s business name."},"address1":{"type":"string","maxLength":38,"description":"First line of the sub-merchant\u2019s street address."},"locality":{"type":"string","maxLength":21,"description":"Sub-merchant\u2019s city."},"administrativeArea":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s state or province. Use the State, Province, and Territory Codes for the United States and Canada.\n"},"postalCode":{"type":"string","maxLength":15,"description":"Partial postal code for the sub-merchant\u2019s address."},"country":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s country. Use the two-character ISO Standard Country Codes."},"email":{"type":"string","maxLength":40,"description":"Sub-merchant\u2019s email address.\n\n**Maximum length for processors**\n\n - American Express Direct: 40\n - CyberSource through VisaNet: 40\n - FDC Compass: 40\n - FDC Nashville Global: 19\n"},"phoneNumber":{"type":"string","maxLength":20,"description":"Sub-merchant\u2019s telephone number.\n\n**Maximum length for procesors**\n\n - American Express Direct: 20\n - CyberSource through VisaNet: 20\n - FDC Compass: 13\n - FDC Nashville Global: 10\n"}}}}},"pointOfSaleInformation":{"type":"object","properties":{"emv":{"type":"object","properties":{"tags":{"type":"string","maxLength":1998,"description":"EMV data that is transmitted from the chip card to the issuer, and from the issuer to the chip card. The EMV\ndata is in the tag-length-value format and includes chip card tags, terminal tags, and transaction detail tags.\n\n`Important` The following tags contain sensitive information and **must not** be included in this field:\n\n - **56**: Track 1 equivalent data\n - **57**: Track 2 equivalent data\n - **5A**: Application PAN\n - **5F20**: Cardholder name\n - **5F24**: Application expiration date (This sensitivity has been relaxed for cmcic, amexdirect, fdiglobal, opdfde, six)\n - **99**: Transaction PIN\n - **9F0B**: Cardholder name (extended)\n - **9F1F**: Track 1 discretionary data\n - **9F20**: Track 2 discretionary data\n\nFor captures, this field is required for contact EMV transactions. Otherwise, it is optional.\n\nFor credits, this field is required for contact EMV stand-alone credits and contactless EMV stand-alone credits.\nOtherwise, it is optional.\n\n`Important` For contact EMV captures, contact EMV stand-alone credits, and contactless EMV stand-alone credits,\nyou must include the following tags in this field. For all other types of EMV transactions, the following tags\nare optional.\n\n - **95**: Terminal verification results\n - **9F10**: Issuer application data\n - **9F26**: Application cryptogram\n"},"fallback":{"type":"boolean","maxLength":5,"description":"Indicates whether a fallback method was used to enter credit card information into the POS terminal. When a\ntechnical problem prevents a successful exchange of information between a chip card and a chip-capable terminal:\n\n 1. Swipe the card or key the credit card information into the POS terminal.\n 2. Use the pos_entry_mode field to indicate whether the information was swiped or keyed.\n\nThis field is supported only on **Chase Paymentech Solutions** and **GPN**.\n","enum":[true,false],"default":false}}}}},"merchantDefinedInformation":{"type":"array","description":"Description of this field is not available.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":50,"description":"Description of this field is not available."},"value":{"type":"string","maxLength":255,"description":"Description of this field is not available."}}}}},"example":{"clientReferenceInformation":{"code":"Testing-Payments-Refund"},"orderInformation":{"amountDetails":{"totalAmount":"102.21","currency":"USD"}}}}},{"name":"id","in":"path","description":"The payment ID. This ID is returned from a previous payment request.","required":true,"type":"string"}],"responses":{"201":{"description":"Successful response.","schema":{"type":"object","title":"ptsV2PaymentsRefundPost201Response","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}},"void":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["PENDING"]},"reconciliationId":{"type":"string","maxLength":60,"description":"The reconciliation id for the submitted transaction. This value is not returned for all processors.\n"},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"refundAmountDetails":{"type":"object","properties":{"refundAmount":{"type":"string","maxLength":15,"description":"Total amount of the refund."},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}},"processorInformation":{"type":"object","properties":{"transactionId":{"type":"string","maxLength":18,"description":"Processor transaction ID.\n\nThis value identifies the transaction on a host system. This value is supported only for Moneris. It contains\nthis information:\n\n - Terminal used to process the transaction\n - Shift during which the transaction took place\n - Batch number\n - Transaction number within the batch\n\nYou must store this value. If you give the customer a receipt, display this value on the receipt.\n\nExample For the value 66012345001069003:\n\n - Terminal ID = 66012345\n - Shift number = 001\n - Batch number = 069\n - Transaction number = 003\n"},"forwardedAcquirerCode":{"type":"string","maxLength":32,"description":"Name of the Japanese acquirer that processed the transaction. Returned only for CCS (CAFIS) and JCN Gateway.\nPlease contact the CyberSource Japan Support Group for more information.\n"}}},"orderInformation":{"type":"object","properties":{"invoiceDetails":{"type":"object","properties":{"level3TransmissionStatus":{"type":"boolean","description":"Indicates whether CyberSource sent the Level III information to the processor. The possible values are:\n\nIf your account is not enabled for Level III data or if you did not include the purchasing level field in your\nrequest, CyberSource does not include the Level III data in the request sent to the processor.\n\nFor processor-specific information, see the bill_purchasing_level3_enabled field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]}}}}}},"example":{"_links":{"self":{"href":"/pts/v2/refunds/4963014779006178301545","method":"GET"},"void":{"href":"/pts/v2/refunds/4963014779006178301545/voids","method":"POST"}},"id":"4963014779006178301545","submitTimeUtc":"2017-06-01T071757Z","status":"200","reconciliationId":"39571012D3DFEKS0","statusInformation":{"reason":"SUCCESS","message":"Successful transaction."},"clientReferenceInformation":{"code":"Testing-Payments-Refund"},"orderInformation":{"amountDetails":{"currency":"USD"}},"refundAmountDetails":{"currency":"USD","refundAmount":"102.21"}}}},"400":{"description":"Invalid request.","schema":{"type":"object","title":"ptsV2PaymentsRefundPost400Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_CARD","INVALID_MERCHANT_CONFIGURATION","CAPTURE_ALREADY_VOIDED","ACCOUNT_NOT_ALLOWED_CREDIT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"type":"object","title":"ptsV2PaymentsRefundPost502Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Refund a Payment","value":{"clientReferenceInformation":{"code":"Testing-Payments-Refund"},"orderInformation":{"amountDetails":{"totalAmount":"102.21","currency":"USD"}}}}}}},"/pts/v2/captures/{id}/refunds":{"post":{"summary":"Refund a Capture","description":"Include the capture ID in the POST request to refund the captured amount.\n","tags":["refund"],"operationId":"refundCapture","parameters":[{"name":"refundCaptureRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"transactionId":{"type":"string","description":"Identifier that you assign to the transaction. See \"Merchant-Initiated Reversals and Voids,\" page 176\n"},"comments":{"type":"string","description":"Comments"}}},"processingInformation":{"type":"object","properties":{"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"reconciliationId":{"type":"string","maxLength":60,"description":"Please check with Cybersource customer support to see if your merchant account is configured correctly so you\ncan include this field in your request.\n* For Payouts: max length for FDCCompass is String (22).\n"},"linkId":{"type":"string","maxLength":26,"description":"Value that links the current payment request to the original request. Set this value\nto the ID that was returned in the reply message from the original payment request.\n\nThis value is used for:\n\n - Partial authorizations.\n - Split shipments.\n"},"reportGroup":{"type":"string","maxLength":25,"description":"Attribute that lets you define custom grouping for your processor reports. This field is supported only for\n**Litle**.\n"},"visaCheckoutId":{"type":"string","maxLength":48,"description":"Identifier for the **Visa Checkout** order. Visa Checkout provides a unique order ID for every transaction in\nthe Visa Checkout **callID** field.\n"},"purchaseLevel":{"type":"string","maxLength":1,"description":"Set this field to 3 to indicate that the request includes Level III data."},"recurringOptions":{"type":"object","properties":{"loanPayment":{"type":"boolean","description":"Flag that indicates whether this is a payment towards an existing contractual loan.\n","enum":[true,false],"default":false}}}}},"paymentInformation":{"type":"object","properties":{"card":{"type":"object","properties":{"number":{"type":"string","maxLength":20,"description":"Customer\u2019s credit card number. Encoded Account Numbers when processing encoded account numbers, use this field\nfor the encoded account number.\n\nFor processor-specific information, see the customer_cc_number field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationMonth":{"type":"string","maxLength":2,"description":"Two-digit month in which the credit card expires. `Format: MM`. Possible values: 01 through 12.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 12.\n\nFor processor-specific information, see the customer_cc_expmo field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationYear":{"type":"string","maxLength":4,"description":"Four-digit year in which the credit card expires. `Format: YYYY`.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 2021.\n\nFor processor-specific information, see the customer_cc_expyr field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"},"accountEncoderId":{"type":"string","maxLength":3,"description":"Identifier for the issuing bank that provided the customer\u2019s encoded account number. Contact your processor\nfor the bank\u2019s ID.\n"},"issueNumber":{"type":"string","maxLength":5,"description":"Number of times a Maestro (UK Domestic) card has been issued to the account holder. The card might or might\nnot have an issue number. The number can consist of one or two digits, and the first digit might be a zero.\nWhen you include this value in your request, include exactly what is printed on the card. A value of 2 is\ndifferent than a value of 02. Do not include the field, even with a blank value, if the card is not a\nMaestro (UK Domestic) card.\n\nThe issue number is not required for Maestro (UK Domestic) transactions.\n"},"startMonth":{"type":"string","maxLength":2,"description":"Month of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: MM`. Possible values: 01 through 12.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"},"startYear":{"type":"string","maxLength":4,"description":"Year of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: YYYY`.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"}}}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"},"discountAmount":{"type":"string","maxLength":15,"description":"Total discount amount applied to the order.\n\nFor processor-specific information, see the order_discount_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"dutyAmount":{"type":"string","maxLength":15,"description":"Total charges for any import or export duties included in the order.\n\nFor processor-specific information, see the duty_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAmount":{"type":"string","maxLength":12,"description":"Total tax amount for all the items in the order.\n\nFor processor-specific information, see the total_tax_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"nationalTaxIncluded":{"type":"string","maxLength":1,"description":"Flag that indicates whether a national tax is included in the order total.\n\nPossible values:\n\n - **0**: national tax not included\n - **1**: national tax included\n\nFor processor-specific information, see the national_tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag that indicates how the merchant manages discounts.\n\nPossible values:\n\n - **0**: no invoice level discount included\n - **1**: tax calculated on the postdiscount invoice total\n - **2**: tax calculated on the prediscount invoice total\n\nFor processor-specific information, see the order_discount_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedLevel":{"type":"string","maxLength":1,"description":"Flag that indicates how you calculate tax.\n\nPossible values:\n\n - **0**: net prices with tax calculated at line item level\n - **1**: net prices with tax calculated at invoice level\n - **2**: gross prices with tax provided at line item level\n - **3**: gross prices with tax provided at invoice level\n - **4**: no tax applies on the invoice for the transaction\n\nFor processor-specific information, see the tax_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxTypeCode":{"type":"string","maxLength":3,"description":"For tax amounts that can be categorized as one tax type.\n\nThis field contains the tax type code that corresponds to the entry in the _lineItems.taxAmount_ field.\n\nPossible values:\n\n - **056**: sales tax (U.S only)\n - **TX~**: all taxes (Canada only) Note ~ = space.\n\nFor processor-specific information, see the total_tax_type_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"freightAmount":{"type":"string","maxLength":13,"description":"Total freight or shipping and handling charges for the order. When you include this field in your request, you\nmust also include the **totalAmount** field.\n\nFor processor-specific information, see the freight_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"foreignAmount":{"type":"string","maxLength":15,"description":"Converted amount returned by the DCC service.\n\nFor processor-specific information, see the foreign_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"foreignCurrency":{"type":"string","maxLength":5,"description":"Billing currency returned by the DCC service.\n\nFor processor-specific information, see the foreign_currency field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRate":{"type":"string","maxLength":13,"description":"Exchange rate returned by the DCC service. Includes a decimal point and a maximum of 4 decimal places.\n\nFor processor-specific information, see the exchange_rate field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRateTimeStamp":{"type":"string","maxLength":14,"description":"Time stamp for the exchange rate. This value is returned by the DCC service.\n\nFormat: `YYYYMMDD~HH:MM` where ~ denotes a space.\n\nFor processor-specific information, see the exchange_rate_timestamp field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amexAdditionalAmounts":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","maxLength":3,"description":"Additional amount type. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount_type field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amount":{"type":"string","maxLength":12,"description":"Additional amount. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}}},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"company":{"type":"string","maxLength":60,"description":"Name of the customer\u2019s company.\n\nFor processor-specific information, see the company_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the billing street address as it appears on the credit card issuer\u2019s records.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address1 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address2":{"type":"string","maxLength":60,"description":"Additional address information.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address2 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":50,"description":"City of the billing address.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_city field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the billing address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_state field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the billing address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_zip field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"email":{"type":"string","maxLength":255,"description":"Customer's email address, including the full domain name.\n\nFor processor-specific information, see the customer_email field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"shipTo":{"type":"object","properties":{"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the shipping address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n"},"country":{"type":"string","maxLength":2,"description":"Country of the shipping address. Use the two character ISO Standard Country Codes."},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the shipping address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n"}}},"lineItems":{"type":"array","items":{"type":"object","properties":{"productCode":{"type":"string","maxLength":255,"description":"Type of product. This value is used to determine the category that the product is in: electronic, handling,\nphysical, service, or shipping. The default value is **default**.\n\nFor a payment, when you set this field to a value other than default or any of the values related to\nshipping and handling, below fields _quantity_, _productName_, and _productSKU_ are required.\n"},"productName":{"type":"string","maxLength":255,"description":"For PAYMENT and CAPTURE API, this field is required when above _productCode_ is not **default** or one of the\nvalues related to shipping and handling.\n"},"productSku":{"type":"string","maxLength":255,"description":"Identification code for the product. For PAYMENT and CAPTURE API, this field is required when above\n_productCode_ is not **default** or one of the values related to shipping and/or handling.\n"},"quantity":{"type":"number","minimum":1,"maximum":9999999999,"description":"For a payment or capture, this field is required when _productCode_ is not **default** or one of the values\nrelated to shipping and handling.\n","default":1},"unitPrice":{"type":"string","maxLength":15,"description":"Per-item price of the product. This value cannot be negative. You can include a decimal point (.), but you\ncannot include any other special characters. CyberSource truncates the amount to the correct number of decimal\nplaces.\n\nFor processor-specific information, see the amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"unitOfMeasure":{"type":"string","maxLength":12,"description":"Unit of measure, or unit of measure code, for the item.\n"},"totalAmount":{"type":"string","maxLength":13,"description":"Total amount for the item. Normally calculated as the unit price x quantity.\n"},"taxAmount":{"type":"string","maxLength":15,"description":"Total tax to apply to the product. This value cannot be negative. The tax amount and the offer amount must\nbe in the same currency. The tax amount field is additive.\n\nThe following example uses a two-exponent currency such as USD:\n\n 1. You include each line item in your request.\n ..- 1st line item has amount=10.00, quantity=1, and taxAmount=0.80\n ..- 2nd line item has amount=20.00, quantity=1, and taxAmount=1.60\n 2. The total amount authorized will be 32.40, not 30.00 with 2.40 of tax included.\n\nThis field is frequently used for Level II and Level III transactions.\n"},"taxRate":{"type":"string","maxLength":7,"description":"Tax rate applied to the item. See \"Numbered Elements,\" page 14.\n\nVisa: Valid range is 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated).\n\nMastercard: Valid range is 0.00001 to 0.99999 (0.001% to 99.999%).\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag to indicate how you handle discount at the line item level.\n\n - 0: no line level discount provided\n - 1: tax was calculated on the post-discount line item total\n - 2: tax was calculated on the pre-discount line item total\n\n`Note` Visa will inset 0 (zero) if an invalid value is included in this field.\n\nThis field relates to the value in the _lineItems[].discountAmount_ field.\n"},"taxStatusIndicator":{"type":"string","maxLength":1,"description":"Flag to indicate whether tax is exempted or not included.\n\n - 0: tax not included\n - 1: tax included\n - 2: transaction is not subject to tax\n"},"taxTypeCode":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"amountIncludesTax":{"type":"boolean","description":"Flag that indicates whether the tax amount is included in the Line Item Total.\n","enum":[true,false]},"typeOfSupply":{"type":"string","maxLength":2,"description":"Flag to indicate whether the purchase is categorized as goods or services.\nPossible values:\n\n - 00: goods\n - 01: services\n"},"commodityCode":{"type":"string","maxLength":15,"description":"Commodity code or International description code used to classify the item. Contact your acquirer for a list of\ncodes.\n"},"discountAmount":{"type":"string","maxLength":13,"description":"Discount applied to the item."},"discountApplied":{"type":"boolean","description":"Flag that indicates whether the amount is discounted.\n\nIf you do not provide a value but you set Discount Amount to a value greater than zero, then CyberSource sets\nthis field to **true**.\n","enum":[true,false]},"discountRate":{"type":"string","maxLength":6,"description":"Rate the item is discounted. Maximum of 2 decimal places.\n\nExample 5.25 (=5.25%)\n"},"invoiceNumber":{"type":"string","maxLength":23,"description":"Field to support an invoice number for a transaction. You must specify the number of line items that will\ninclude an invoice number. By default, the first line item will include an invoice number field. The invoice\nnumber field can be included for up to 10 line items.\n"},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}}}}},"invoiceDetails":{"type":"object","properties":{"purchaseOrderNumber":{"type":"string","maxLength":25,"description":"Value used by your customer to identify the order. This value is typically a purchase order number. CyberSource\nrecommends that you do not populate the field with all zeros or nines.\n\nFor processor-specific information, see the user_po field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseOrderDate":{"type":"string","maxLength":10,"description":"Date the order was processed. `Format: YYYY-MM-DD`.\n\nFor processor-specific information, see the purchaser_order_date field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseContactName":{"type":"string","maxLength":36,"description":"The name of the individual or the company contacted for company authorized purchases.\n\nFor processor-specific information, see the authorized_contact_name field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxable":{"type":"boolean","description":"Flag that indicates whether an order is taxable. This value must be true if the sum of all _lineItems[].taxAmount_ values > 0.\n\nIf you do not include any _lineItems[].taxAmount_ values in your request, CyberSource does not include\n_invoiceDetails.taxable_ in the data it sends to the processor.\n\nFor processor-specific information, see the tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]},"vatInvoiceReferenceNumber":{"type":"string","maxLength":15,"description":"VAT invoice number associated with the transaction.\n\nFor processor-specific information, see the vat_invoice_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"commodityCode":{"type":"string","maxLength":4,"description":"International description code of the overall order\u2019s goods or services or the Categorizes purchases for VAT\nreporting. Contact your acquirer for a list of codes.\n\nFor processor-specific information, see the summary_commodity_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"transactionAdviceAddendum":{"type":"array","items":{"type":"object","properties":{"data":{"type":"string","maxLength":40,"description":"Four Transaction Advice Addendum (TAA) fields. These fields are used to display descriptive information\nabout a transaction on the customer\u2019s American Express card statement. When you send TAA fields, start\nwith amexdata_taa1, then ...taa2, and so on. Skipping a TAA field causes subsequent TAA fields to be\nignored.\n\nTo use these fields, contact CyberSource Customer Support to have your account enabled for this feature.\n"}}}}}},"shippingDetails":{"type":"object","properties":{"shipFromPostalCode":{"type":"string","maxLength":10,"description":"Postal code for the address from which the goods are shipped, which is used to establish nexus. The default is\nthe postal code associated with your CyberSource account.\n\nThe postal code must consist of 5 to 9 digits. When the billing country is the U.S., the 9-digit postal code\nmust follow this format:\n\n`[5 digits][dash][4 digits]`\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n\n`[alpha][numeric][alpha][space] [numeric][alpha][numeric]`\n\nExample A1B 2C3\n\nThis field is frequently used for Level II and Level III transactions.\n"}}}}},"buyerInformation":{"type":"object","properties":{"merchantCustomerId":{"type":"string","maxLength":100,"description":"Your identifier for the customer.\n\nFor processor-specific information, see the customer_account_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":20,"description":"Customer\u2019s government-assigned tax identification number.\n\nFor processor-specific information, see the purchaser_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"}}},"deviceInformation":{"type":"object","properties":{"hostName":{"type":"string","maxLength":60,"description":"DNS resolved hostname from above _ipAddress_."},"ipAddress":{"type":"string","maxLength":15,"description":"IP address of the customer."},"userAgent":{"type":"string","maxLength":40,"description":"Customer\u2019s browser as identified from the HTTP header data. For example, Mozilla is the value that identifies\nthe Netscape browser.\n"}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"name":{"type":"string","maxLength":23,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\nFor Payouts:\n* Paymentech (22)\n"},"alternateName":{"type":"string","maxLength":13,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"contact":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n* FDCCompass (13)\n* Paymentech (13)\n"},"address1":{"type":"string","maxLength":60,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":13,"description":"Merchant City. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":3,"description":"Merchant State. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"categoryCode":{"type":"integer","maximum":9999,"description":"Four-digit number that the payment card industry uses to classify merchants into market segments. Visa assigned\none or more of these values to your business when you started accepting Visa cards.\n\nIf you do not include this field in your request, CyberSource uses the value in your CyberSource account.\n\nFor processor-specific information, see the merchant_category_code field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":21,"description":"Your government-assigned tax identification number.\n\nFor CtV processors, the maximum length is 20.\n\nFor other processor-specific information, see the merchant_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"cardAcceptorReferenceNumber":{"type":"string","maxLength":25,"description":"Reference number that facilitates card acceptor/corporation communication and record keeping.\n\nFor processor-specific information, see the card_acceptor_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"}}},"aggregatorInformation":{"type":"object","properties":{"aggregatorId":{"type":"string","maxLength":20,"description":"Value that identifies you as a payment aggregator. Get this value from the\nprocessor.\n\nFor processor-specific information, see the aggregator_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"name":{"type":"string","maxLength":37,"description":"Your payment aggregator business name.\n\nFor processor-specific information, see the aggregator_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"subMerchant":{"type":"object","properties":{"name":{"type":"string","maxLength":37,"description":"Sub-merchant\u2019s business name."},"address1":{"type":"string","maxLength":38,"description":"First line of the sub-merchant\u2019s street address."},"locality":{"type":"string","maxLength":21,"description":"Sub-merchant\u2019s city."},"administrativeArea":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s state or province. Use the State, Province, and Territory Codes for the United States and Canada.\n"},"postalCode":{"type":"string","maxLength":15,"description":"Partial postal code for the sub-merchant\u2019s address."},"country":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s country. Use the two-character ISO Standard Country Codes."},"email":{"type":"string","maxLength":40,"description":"Sub-merchant\u2019s email address.\n\n**Maximum length for processors**\n\n - American Express Direct: 40\n - CyberSource through VisaNet: 40\n - FDC Compass: 40\n - FDC Nashville Global: 19\n"},"phoneNumber":{"type":"string","maxLength":20,"description":"Sub-merchant\u2019s telephone number.\n\n**Maximum length for procesors**\n\n - American Express Direct: 20\n - CyberSource through VisaNet: 20\n - FDC Compass: 13\n - FDC Nashville Global: 10\n"}}}}},"pointOfSaleInformation":{"type":"object","properties":{"emv":{"type":"object","properties":{"tags":{"type":"string","maxLength":1998,"description":"EMV data that is transmitted from the chip card to the issuer, and from the issuer to the chip card. The EMV\ndata is in the tag-length-value format and includes chip card tags, terminal tags, and transaction detail tags.\n\n`Important` The following tags contain sensitive information and **must not** be included in this field:\n\n - **56**: Track 1 equivalent data\n - **57**: Track 2 equivalent data\n - **5A**: Application PAN\n - **5F20**: Cardholder name\n - **5F24**: Application expiration date (This sensitivity has been relaxed for cmcic, amexdirect, fdiglobal, opdfde, six)\n - **99**: Transaction PIN\n - **9F0B**: Cardholder name (extended)\n - **9F1F**: Track 1 discretionary data\n - **9F20**: Track 2 discretionary data\n\nFor captures, this field is required for contact EMV transactions. Otherwise, it is optional.\n\nFor credits, this field is required for contact EMV stand-alone credits and contactless EMV stand-alone credits.\nOtherwise, it is optional.\n\n`Important` For contact EMV captures, contact EMV stand-alone credits, and contactless EMV stand-alone credits,\nyou must include the following tags in this field. For all other types of EMV transactions, the following tags\nare optional.\n\n - **95**: Terminal verification results\n - **9F10**: Issuer application data\n - **9F26**: Application cryptogram\n"},"fallback":{"type":"boolean","maxLength":5,"description":"Indicates whether a fallback method was used to enter credit card information into the POS terminal. When a\ntechnical problem prevents a successful exchange of information between a chip card and a chip-capable terminal:\n\n 1. Swipe the card or key the credit card information into the POS terminal.\n 2. Use the pos_entry_mode field to indicate whether the information was swiped or keyed.\n\nThis field is supported only on **Chase Paymentech Solutions** and **GPN**.\n","enum":[true,false],"default":false}}}}},"merchantDefinedInformation":{"type":"array","description":"Description of this field is not available.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":50,"description":"Description of this field is not available."},"value":{"type":"string","maxLength":255,"description":"Description of this field is not available."}}}}},"example":{"clientReferenceInformation":{"code":"Testing-Payments-Refund"},"orderInformation":{"amountDetails":{"totalAmount":"102.21","currency":"USD"}}}}},{"name":"id","in":"path","description":"The capture ID. This ID is returned from a previous capture request.","required":true,"type":"string"}],"responses":{"201":{"description":"Successful response.","schema":{"type":"object","title":"ptsV2CapturesRefundsPost201Response","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}},"void":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["PENDING"]},"reconciliationId":{"type":"string","maxLength":60,"description":"The reconciliation id for the submitted transaction. This value is not returned for all processors.\n"},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"refundAmountDetails":{"type":"object","properties":{"refundAmount":{"type":"string","maxLength":15,"description":"Total amount of the refund."},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}},"processorInformation":{"type":"object","properties":{"transactionId":{"type":"string","maxLength":18,"description":"Processor transaction ID.\n\nThis value identifies the transaction on a host system. This value is supported only for Moneris. It contains\nthis information:\n\n - Terminal used to process the transaction\n - Shift during which the transaction took place\n - Batch number\n - Transaction number within the batch\n\nYou must store this value. If you give the customer a receipt, display this value on the receipt.\n\nExample For the value 66012345001069003:\n\n - Terminal ID = 66012345\n - Shift number = 001\n - Batch number = 069\n - Transaction number = 003\n"},"forwardedAcquirerCode":{"type":"string","maxLength":32,"description":"Name of the Japanese acquirer that processed the transaction. Returned only for CCS (CAFIS) and JCN Gateway.\nPlease contact the CyberSource Japan Support Group for more information.\n"}}},"orderInformation":{"type":"object","properties":{"invoiceDetails":{"type":"object","properties":{"level3TransmissionStatus":{"type":"boolean","description":"Indicates whether CyberSource sent the Level III information to the processor. The possible values are:\n\nIf your account is not enabled for Level III data or if you did not include the purchasing level field in your\nrequest, CyberSource does not include the Level III data in the request sent to the processor.\n\nFor processor-specific information, see the bill_purchasing_level3_enabled field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]}}}}}},"example":{"_links":{"self":{"href":"/pts/v2/refunds/4963014779006178301545","method":"GET"},"void":{"href":"/pts/v2/refunds/4963014779006178301545/voids","method":"POST"}},"id":"4963014779006178301545","submitTimeUtc":"2017-06-01T071757Z","status":"200","reconciliationId":"39571012D3DFEKS0","statusInformation":{"reason":"SUCCESS","message":"Successful transaction."},"clientReferenceInformation":{"code":"Testing-Payments-Refund"},"orderInformation":{"amountDetails":{"currency":"USD"}},"refundAmountDetails":{"currency":"USD","refundAmount":"102.21"}}}},"400":{"description":"Invalid request.","schema":{"title":"ptsV2CapturesRefundsPost400Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_CARD","INVALID_MERCHANT_CONFIGURATION","CAPTURE_ALREADY_VOIDED","ACCOUNT_NOT_ALLOWED_CREDIT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"title":"ptsV2CapturesRefundsPost502Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Refund a Capture","value":{"clientReferenceInformation":{"code":"Testing-Payments-Refund"},"orderInformation":{"amountDetails":{"totalAmount":"102.21","currency":"USD"}}}}}}},"/pts/v2/credits/":{"post":{"summary":"Process a Credit","description":"POST to the credit resource to credit funds to a specified credit card.","tags":["credit"],"operationId":"createCredit","parameters":[{"name":"createCreditRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"transactionId":{"type":"string","description":"Identifier that you assign to the transaction. See \"Merchant-Initiated Reversals and Voids,\" page 176\n"},"comments":{"type":"string","description":"Comments"}}},"processingInformation":{"type":"object","properties":{"commerceIndicator":{"type":"string","maxLength":20,"description":"Type of transaction. Some payment card companies use this information when determining discount rates. When you\nomit this field for **Ingenico ePayments**, the processor uses the default transaction type they have on file\nfor you instead of the default value listed here.\n"},"processorId":{"type":"string","maxLength":3,"description":"Value that identifies the processor/acquirer to use for the transaction. This value is supported only for\n**CyberSource through VisaNet**.\n"},"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"reconciliationId":{"type":"string","maxLength":60,"description":"Please check with Cybersource customer support to see if your merchant account is configured correctly so you\ncan include this field in your request.\n* For Payouts: max length for FDCCompass is String (22).\n"},"linkId":{"type":"string","maxLength":26,"description":"Value that links the current payment request to the original request. Set this value\nto the ID that was returned in the reply message from the original payment request.\n\nThis value is used for:\n\n - Partial authorizations.\n - Split shipments.\n"},"reportGroup":{"type":"string","maxLength":25,"description":"Attribute that lets you define custom grouping for your processor reports. This field is supported only for\n**Litle**.\n"},"visaCheckoutId":{"type":"string","maxLength":48,"description":"Identifier for the **Visa Checkout** order. Visa Checkout provides a unique order ID for every transaction in\nthe Visa Checkout **callID** field.\n"},"purchaseLevel":{"type":"string","maxLength":1,"description":"Set this field to 3 to indicate that the request includes Level III data."},"recurringOptions":{"type":"object","properties":{"loanPayment":{"type":"boolean","description":"Flag that indicates whether this is a payment towards an existing contractual loan.\n","enum":[true,false],"default":false}}}}},"paymentInformation":{"type":"object","properties":{"card":{"type":"object","properties":{"number":{"type":"string","maxLength":20,"description":"Customer\u2019s credit card number. Encoded Account Numbers when processing encoded account numbers, use this field\nfor the encoded account number.\n\nFor processor-specific information, see the customer_cc_number field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationMonth":{"type":"string","maxLength":2,"description":"Two-digit month in which the credit card expires. `Format: MM`. Possible values: 01 through 12.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 12.\n\nFor processor-specific information, see the customer_cc_expmo field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationYear":{"type":"string","maxLength":4,"description":"Four-digit year in which the credit card expires. `Format: YYYY`.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 2021.\n\nFor processor-specific information, see the customer_cc_expyr field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"},"accountEncoderId":{"type":"string","maxLength":3,"description":"Identifier for the issuing bank that provided the customer\u2019s encoded account number. Contact your processor\nfor the bank\u2019s ID.\n"},"issueNumber":{"type":"string","maxLength":5,"description":"Number of times a Maestro (UK Domestic) card has been issued to the account holder. The card might or might\nnot have an issue number. The number can consist of one or two digits, and the first digit might be a zero.\nWhen you include this value in your request, include exactly what is printed on the card. A value of 2 is\ndifferent than a value of 02. Do not include the field, even with a blank value, if the card is not a\nMaestro (UK Domestic) card.\n\nThe issue number is not required for Maestro (UK Domestic) transactions.\n"},"startMonth":{"type":"string","maxLength":2,"description":"Month of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: MM`. Possible values: 01 through 12.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"},"startYear":{"type":"string","maxLength":4,"description":"Year of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: YYYY`.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"}}}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"},"discountAmount":{"type":"string","maxLength":15,"description":"Total discount amount applied to the order.\n\nFor processor-specific information, see the order_discount_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"dutyAmount":{"type":"string","maxLength":15,"description":"Total charges for any import or export duties included in the order.\n\nFor processor-specific information, see the duty_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAmount":{"type":"string","maxLength":12,"description":"Total tax amount for all the items in the order.\n\nFor processor-specific information, see the total_tax_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"nationalTaxIncluded":{"type":"string","maxLength":1,"description":"Flag that indicates whether a national tax is included in the order total.\n\nPossible values:\n\n - **0**: national tax not included\n - **1**: national tax included\n\nFor processor-specific information, see the national_tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag that indicates how the merchant manages discounts.\n\nPossible values:\n\n - **0**: no invoice level discount included\n - **1**: tax calculated on the postdiscount invoice total\n - **2**: tax calculated on the prediscount invoice total\n\nFor processor-specific information, see the order_discount_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxAppliedLevel":{"type":"string","maxLength":1,"description":"Flag that indicates how you calculate tax.\n\nPossible values:\n\n - **0**: net prices with tax calculated at line item level\n - **1**: net prices with tax calculated at invoice level\n - **2**: gross prices with tax provided at line item level\n - **3**: gross prices with tax provided at invoice level\n - **4**: no tax applies on the invoice for the transaction\n\nFor processor-specific information, see the tax_management_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxTypeCode":{"type":"string","maxLength":3,"description":"For tax amounts that can be categorized as one tax type.\n\nThis field contains the tax type code that corresponds to the entry in the _lineItems.taxAmount_ field.\n\nPossible values:\n\n - **056**: sales tax (U.S only)\n - **TX~**: all taxes (Canada only) Note ~ = space.\n\nFor processor-specific information, see the total_tax_type_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"freightAmount":{"type":"string","maxLength":13,"description":"Total freight or shipping and handling charges for the order. When you include this field in your request, you\nmust also include the **totalAmount** field.\n\nFor processor-specific information, see the freight_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"foreignAmount":{"type":"string","maxLength":15,"description":"Converted amount returned by the DCC service.\n\nFor processor-specific information, see the foreign_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"foreignCurrency":{"type":"string","maxLength":5,"description":"Billing currency returned by the DCC service.\n\nFor processor-specific information, see the foreign_currency field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRate":{"type":"string","maxLength":13,"description":"Exchange rate returned by the DCC service. Includes a decimal point and a maximum of 4 decimal places.\n\nFor processor-specific information, see the exchange_rate field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"exchangeRateTimeStamp":{"type":"string","maxLength":14,"description":"Time stamp for the exchange rate. This value is returned by the DCC service.\n\nFormat: `YYYYMMDD~HH:MM` where ~ denotes a space.\n\nFor processor-specific information, see the exchange_rate_timestamp field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amexAdditionalAmounts":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","maxLength":3,"description":"Additional amount type. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount_type field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"amount":{"type":"string","maxLength":12,"description":"Additional amount. This field is supported only for **American Express Direct**.\n\nFor processor-specific information, see the additional_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}}},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"company":{"type":"string","maxLength":60,"description":"Name of the customer\u2019s company.\n\nFor processor-specific information, see the company_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the billing street address as it appears on the credit card issuer\u2019s records.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address1 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address2":{"type":"string","maxLength":60,"description":"Additional address information.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address2 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":50,"description":"City of the billing address.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_city field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the billing address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_state field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the billing address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_zip field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"email":{"type":"string","maxLength":255,"description":"Customer's email address, including the full domain name.\n\nFor processor-specific information, see the customer_email field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"shipTo":{"type":"object","properties":{"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the shipping address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n"},"country":{"type":"string","maxLength":2,"description":"Country of the shipping address. Use the two character ISO Standard Country Codes."},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the shipping address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n"}}},"lineItems":{"type":"array","items":{"type":"object","properties":{"productCode":{"type":"string","maxLength":255,"description":"Type of product. This value is used to determine the category that the product is in: electronic, handling,\nphysical, service, or shipping. The default value is **default**.\n\nFor a payment, when you set this field to a value other than default or any of the values related to\nshipping and handling, below fields _quantity_, _productName_, and _productSKU_ are required.\n"},"productName":{"type":"string","maxLength":255,"description":"For PAYMENT and CAPTURE API, this field is required when above _productCode_ is not **default** or one of the\nvalues related to shipping and handling.\n"},"productSku":{"type":"string","maxLength":255,"description":"Identification code for the product. For PAYMENT and CAPTURE API, this field is required when above\n_productCode_ is not **default** or one of the values related to shipping and/or handling.\n"},"quantity":{"type":"number","minimum":1,"maximum":9999999999,"description":"For a payment or capture, this field is required when _productCode_ is not **default** or one of the values\nrelated to shipping and handling.\n","default":1},"unitPrice":{"type":"string","maxLength":15,"description":"Per-item price of the product. This value cannot be negative. You can include a decimal point (.), but you\ncannot include any other special characters. CyberSource truncates the amount to the correct number of decimal\nplaces.\n\nFor processor-specific information, see the amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"unitOfMeasure":{"type":"string","maxLength":12,"description":"Unit of measure, or unit of measure code, for the item.\n"},"totalAmount":{"type":"string","maxLength":13,"description":"Total amount for the item. Normally calculated as the unit price x quantity.\n"},"taxAmount":{"type":"string","maxLength":15,"description":"Total tax to apply to the product. This value cannot be negative. The tax amount and the offer amount must\nbe in the same currency. The tax amount field is additive.\n\nThe following example uses a two-exponent currency such as USD:\n\n 1. You include each line item in your request.\n ..- 1st line item has amount=10.00, quantity=1, and taxAmount=0.80\n ..- 2nd line item has amount=20.00, quantity=1, and taxAmount=1.60\n 2. The total amount authorized will be 32.40, not 30.00 with 2.40 of tax included.\n\nThis field is frequently used for Level II and Level III transactions.\n"},"taxRate":{"type":"string","maxLength":7,"description":"Tax rate applied to the item. See \"Numbered Elements,\" page 14.\n\nVisa: Valid range is 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated).\n\nMastercard: Valid range is 0.00001 to 0.99999 (0.001% to 99.999%).\n"},"taxAppliedAfterDiscount":{"type":"string","maxLength":1,"description":"Flag to indicate how you handle discount at the line item level.\n\n - 0: no line level discount provided\n - 1: tax was calculated on the post-discount line item total\n - 2: tax was calculated on the pre-discount line item total\n\n`Note` Visa will inset 0 (zero) if an invalid value is included in this field.\n\nThis field relates to the value in the _lineItems[].discountAmount_ field.\n"},"taxStatusIndicator":{"type":"string","maxLength":1,"description":"Flag to indicate whether tax is exempted or not included.\n\n - 0: tax not included\n - 1: tax included\n - 2: transaction is not subject to tax\n"},"taxTypeCode":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"amountIncludesTax":{"type":"boolean","description":"Flag that indicates whether the tax amount is included in the Line Item Total.\n","enum":[true,false]},"typeOfSupply":{"type":"string","maxLength":2,"description":"Flag to indicate whether the purchase is categorized as goods or services.\nPossible values:\n\n - 00: goods\n - 01: services\n"},"commodityCode":{"type":"string","maxLength":15,"description":"Commodity code or International description code used to classify the item. Contact your acquirer for a list of\ncodes.\n"},"discountAmount":{"type":"string","maxLength":13,"description":"Discount applied to the item."},"discountApplied":{"type":"boolean","description":"Flag that indicates whether the amount is discounted.\n\nIf you do not provide a value but you set Discount Amount to a value greater than zero, then CyberSource sets\nthis field to **true**.\n","enum":[true,false]},"discountRate":{"type":"string","maxLength":6,"description":"Rate the item is discounted. Maximum of 2 decimal places.\n\nExample 5.25 (=5.25%)\n"},"invoiceNumber":{"type":"string","maxLength":23,"description":"Field to support an invoice number for a transaction. You must specify the number of line items that will\ninclude an invoice number. By default, the first line item will include an invoice number field. The invoice\nnumber field can be included for up to 10 line items.\n"},"taxDetails":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"This is used to determine what type of tax related data should be inclued under _taxDetails_ object.\n","enum":["alternate","local","national","vat"]},"amount":{"type":"string","maxLength":13,"description":"Please see below table for related decription based on above _type_ field.\n\n| type | amount description |\n|-----------|--------------------|\n| alternate | Total amount of alternate tax for the order. |\n| local | Sales tax for the order. |\n| national | National tax for the order. |\n| vat | Total amount of VAT or other tax included in the order. |\n"},"rate":{"type":"string","maxLength":6,"description":"Rate of VAT or other tax for the order.\n\nExample 0.040 (=4%)\n\nValid range: 0.01 to 0.99 (1% to 99%, with only whole percentage values accepted; values with additional\ndecimal places will be truncated)\n"},"code":{"type":"string","maxLength":4,"description":"Type of tax being applied to the item. Possible values:\n\nBelow values are used by **RBS WorldPay Atlanta**, **FDC Nashville Global**, **Litle**\n\n - 0000: unknown tax type\n - 0001: federal/national sales tax\n - 0002: state sales tax\n - 0003: city sales tax\n - 0004: local sales tax\n - 0005: municipal sales tax\n - 0006: other tax\n - 0010: value-added tax\n - 0011: goods and services tax\n - 0012: provincial sales tax\n - 0013: harmonized sales tax\n - 0014: Quebec sales tax (QST)\n - 0020: room tax\n - 0021: occupancy tax\n - 0022: energy tax\n - Blank: Tax not supported on line item.\n"},"taxId":{"type":"string","maxLength":15,"description":"Your tax ID number to use for the alternate tax amount. Required if you set alternate tax amount to any value,\nincluding zero. You may send this field without sending alternate tax amount.\n"},"applied":{"type":"boolean","description":"The tax is applied. Valid value is `true` or `false`."}}}}}}},"invoiceDetails":{"type":"object","properties":{"purchaseOrderNumber":{"type":"string","maxLength":25,"description":"Value used by your customer to identify the order. This value is typically a purchase order number. CyberSource\nrecommends that you do not populate the field with all zeros or nines.\n\nFor processor-specific information, see the user_po field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseOrderDate":{"type":"string","maxLength":10,"description":"Date the order was processed. `Format: YYYY-MM-DD`.\n\nFor processor-specific information, see the purchaser_order_date field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"purchaseContactName":{"type":"string","maxLength":36,"description":"The name of the individual or the company contacted for company authorized purchases.\n\nFor processor-specific information, see the authorized_contact_name field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"taxable":{"type":"boolean","description":"Flag that indicates whether an order is taxable. This value must be true if the sum of all _lineItems[].taxAmount_ values > 0.\n\nIf you do not include any _lineItems[].taxAmount_ values in your request, CyberSource does not include\n_invoiceDetails.taxable_ in the data it sends to the processor.\n\nFor processor-specific information, see the tax_indicator field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]},"vatInvoiceReferenceNumber":{"type":"string","maxLength":15,"description":"VAT invoice number associated with the transaction.\n\nFor processor-specific information, see the vat_invoice_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"commodityCode":{"type":"string","maxLength":4,"description":"International description code of the overall order\u2019s goods or services or the Categorizes purchases for VAT\nreporting. Contact your acquirer for a list of codes.\n\nFor processor-specific information, see the summary_commodity_code field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"transactionAdviceAddendum":{"type":"array","items":{"type":"object","properties":{"data":{"type":"string","maxLength":40,"description":"Four Transaction Advice Addendum (TAA) fields. These fields are used to display descriptive information\nabout a transaction on the customer\u2019s American Express card statement. When you send TAA fields, start\nwith amexdata_taa1, then ...taa2, and so on. Skipping a TAA field causes subsequent TAA fields to be\nignored.\n\nTo use these fields, contact CyberSource Customer Support to have your account enabled for this feature.\n"}}}}}},"shippingDetails":{"type":"object","properties":{"shipFromPostalCode":{"type":"string","maxLength":10,"description":"Postal code for the address from which the goods are shipped, which is used to establish nexus. The default is\nthe postal code associated with your CyberSource account.\n\nThe postal code must consist of 5 to 9 digits. When the billing country is the U.S., the 9-digit postal code\nmust follow this format:\n\n`[5 digits][dash][4 digits]`\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n\n`[alpha][numeric][alpha][space] [numeric][alpha][numeric]`\n\nExample A1B 2C3\n\nThis field is frequently used for Level II and Level III transactions.\n"}}}}},"buyerInformation":{"type":"object","properties":{"merchantCustomerId":{"type":"string","maxLength":100,"description":"Your identifier for the customer.\n\nFor processor-specific information, see the customer_account_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":20,"description":"Customer\u2019s government-assigned tax identification number.\n\nFor processor-specific information, see the purchaser_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"}}},"deviceInformation":{"type":"object","properties":{"hostName":{"type":"string","maxLength":60,"description":"DNS resolved hostname from above _ipAddress_."},"ipAddress":{"type":"string","maxLength":15,"description":"IP address of the customer."},"userAgent":{"type":"string","maxLength":40,"description":"Customer\u2019s browser as identified from the HTTP header data. For example, Mozilla is the value that identifies\nthe Netscape browser.\n"}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"name":{"type":"string","maxLength":23,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\nFor Payouts:\n* Paymentech (22)\n"},"alternateName":{"type":"string","maxLength":13,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"contact":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n* FDCCompass (13)\n* Paymentech (13)\n"},"address1":{"type":"string","maxLength":60,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":13,"description":"Merchant City. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":3,"description":"Merchant State. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"categoryCode":{"type":"integer","maximum":9999,"description":"Four-digit number that the payment card industry uses to classify merchants into market segments. Visa assigned\none or more of these values to your business when you started accepting Visa cards.\n\nIf you do not include this field in your request, CyberSource uses the value in your CyberSource account.\n\nFor processor-specific information, see the merchant_category_code field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"vatRegistrationNumber":{"type":"string","maxLength":21,"description":"Your government-assigned tax identification number.\n\nFor CtV processors, the maximum length is 20.\n\nFor other processor-specific information, see the merchant_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"cardAcceptorReferenceNumber":{"type":"string","maxLength":25,"description":"Reference number that facilitates card acceptor/corporation communication and record keeping.\n\nFor processor-specific information, see the card_acceptor_ref_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"}}},"aggregatorInformation":{"type":"object","properties":{"aggregatorId":{"type":"string","maxLength":20,"description":"Value that identifies you as a payment aggregator. Get this value from the\nprocessor.\n\nFor processor-specific information, see the aggregator_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"name":{"type":"string","maxLength":37,"description":"Your payment aggregator business name.\n\nFor processor-specific information, see the aggregator_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"subMerchant":{"type":"object","properties":{"name":{"type":"string","maxLength":37,"description":"Sub-merchant\u2019s business name."},"address1":{"type":"string","maxLength":38,"description":"First line of the sub-merchant\u2019s street address."},"locality":{"type":"string","maxLength":21,"description":"Sub-merchant\u2019s city."},"administrativeArea":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s state or province. Use the State, Province, and Territory Codes for the United States and Canada.\n"},"postalCode":{"type":"string","maxLength":15,"description":"Partial postal code for the sub-merchant\u2019s address."},"country":{"type":"string","maxLength":3,"description":"Sub-merchant\u2019s country. Use the two-character ISO Standard Country Codes."},"email":{"type":"string","maxLength":40,"description":"Sub-merchant\u2019s email address.\n\n**Maximum length for processors**\n\n - American Express Direct: 40\n - CyberSource through VisaNet: 40\n - FDC Compass: 40\n - FDC Nashville Global: 19\n"},"phoneNumber":{"type":"string","maxLength":20,"description":"Sub-merchant\u2019s telephone number.\n\n**Maximum length for procesors**\n\n - American Express Direct: 20\n - CyberSource through VisaNet: 20\n - FDC Compass: 13\n - FDC Nashville Global: 10\n"}}}}},"pointOfSaleInformation":{"type":"object","properties":{"emv":{"type":"object","properties":{"tags":{"type":"string","maxLength":1998,"description":"EMV data that is transmitted from the chip card to the issuer, and from the issuer to the chip card. The EMV\ndata is in the tag-length-value format and includes chip card tags, terminal tags, and transaction detail tags.\n\n`Important` The following tags contain sensitive information and **must not** be included in this field:\n\n - **56**: Track 1 equivalent data\n - **57**: Track 2 equivalent data\n - **5A**: Application PAN\n - **5F20**: Cardholder name\n - **5F24**: Application expiration date (This sensitivity has been relaxed for cmcic, amexdirect, fdiglobal, opdfde, six)\n - **99**: Transaction PIN\n - **9F0B**: Cardholder name (extended)\n - **9F1F**: Track 1 discretionary data\n - **9F20**: Track 2 discretionary data\n\nFor captures, this field is required for contact EMV transactions. Otherwise, it is optional.\n\nFor credits, this field is required for contact EMV stand-alone credits and contactless EMV stand-alone credits.\nOtherwise, it is optional.\n\n`Important` For contact EMV captures, contact EMV stand-alone credits, and contactless EMV stand-alone credits,\nyou must include the following tags in this field. For all other types of EMV transactions, the following tags\nare optional.\n\n - **95**: Terminal verification results\n - **9F10**: Issuer application data\n - **9F26**: Application cryptogram\n"},"fallback":{"type":"boolean","maxLength":5,"description":"Indicates whether a fallback method was used to enter credit card information into the POS terminal. When a\ntechnical problem prevents a successful exchange of information between a chip card and a chip-capable terminal:\n\n 1. Swipe the card or key the credit card information into the POS terminal.\n 2. Use the pos_entry_mode field to indicate whether the information was swiped or keyed.\n\nThis field is supported only on **Chase Paymentech Solutions** and **GPN**.\n","enum":[true,false],"default":false},"fallbackCondition":{"type":"number","description":"Reason for the EMV fallback transaction. An EMV fallback transaction occurs when an EMV transaction fails for\none of these reasons:\n\n - Technical failure: the EMV terminal or EMV card cannot read and process chip data.\n - Empty candidate list failure: the EMV terminal does not have any applications in common with the EMV card.\n EMV terminals are coded to determine whether the terminal and EMV card have any applications in common.\n EMV terminals provide this information to you.\n\nPossible values:\n\n - **1**: Transaction was initiated with information from a magnetic stripe, and the previous transaction at the\n EMV terminal either used information from a successful chip read or it was not a chip transaction.\n - **2**: Transaction was initiated with information from a magnetic stripe, and the previous transaction at the\n EMV terminal was an EMV fallback transaction because the attempted chip read was unsuccessful.\n\nThis field is supported only on **GPN**.\n"}}}}},"merchantDefinedInformation":{"type":"array","description":"Description of this field is not available.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":50,"description":"Description of this field is not available."},"value":{"type":"string","maxLength":255,"description":"Description of this field is not available."}}}}},"example":{"clientReferenceInformation":{"code":"12345678"},"orderInformation":{"billTo":{"country":"US","firstName":"Test","lastName":"test","phoneNumber":"9999999999","address1":"test","postalCode":"48104-2201","locality":"Ann Arbor","administrativeArea":"MI","email":"test@cybs.com"},"amountDetails":{"totalAmount":"200","currency":"usd"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"4111111111111111","expirationMonth":"03","type":"001"}}}}}],"responses":{"201":{"description":"Successful response.","schema":{"title":"ptsV2CreditsPost201Response","type":"object","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}},"void":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["PENDING"]},"reconciliationId":{"type":"string","maxLength":60,"description":"The reconciliation id for the submitted transaction. This value is not returned for all processors.\n"},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"creditAmountDetails":{"type":"object","properties":{"creditAmount":{"type":"string","maxLength":15,"description":"Total amount of the credit."},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}},"processorInformation":{"type":"object","properties":{"transactionId":{"type":"string","maxLength":18,"description":"Processor transaction ID.\n\nThis value identifies the transaction on a host system. This value is supported only for Moneris. It contains\nthis information:\n\n - Terminal used to process the transaction\n - Shift during which the transaction took place\n - Batch number\n - Transaction number within the batch\n\nYou must store this value. If you give the customer a receipt, display this value on the receipt.\n\nExample For the value 66012345001069003:\n\n - Terminal ID = 66012345\n - Shift number = 001\n - Batch number = 069\n - Transaction number = 003\n"},"forwardedAcquirerCode":{"type":"string","maxLength":32,"description":"Name of the Japanese acquirer that processed the transaction. Returned only for CCS (CAFIS) and JCN Gateway.\nPlease contact the CyberSource Japan Support Group for more information.\n"}}},"orderInformation":{"type":"object","properties":{"invoiceDetails":{"type":"object","properties":{"level3TransmissionStatus":{"type":"boolean","description":"Indicates whether CyberSource sent the Level III information to the processor. The possible values are:\n\nIf your account is not enabled for Level III data or if you did not include the purchasing level field in your\nrequest, CyberSource does not include the Level III data in the request sent to the processor.\n\nFor processor-specific information, see the bill_purchasing_level3_enabled field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n","enum":[true,false]}}}}}},"example":{"_links":{"self":{"href":"/pts/v2/credits/4963014324246004901546","method":"GET"},"void":{"href":"/pts/v2/credits/4963014324246004901546/voids","method":"POST"}},"id":"4963014324246004901546","submitTimeUtc":"2017-06-01T071712Z","status":"200","reconciliationId":"39570714X3E1LBQ8","statusInformation":{"reason":"SUCCESS","message":"Successful transaction."},"clientReferenceInformation":{"code":"12345678"},"creditAmountDetails":{"currency":"usd","creditAmount":"200.00"},"orderInformation":{"amountDetails":{"currency":"usd"}}}}},"400":{"description":"Invalid request.","schema":{"title":"ptsV2CreditsPost400Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_CARD","INVALID_MERCHANT_CONFIGURATION","CAPTURE_ALREADY_VOIDED","ACCOUNT_NOT_ALLOWED_CREDIT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"title":"ptsV2CreditsPost502Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Credit","value":{"clientReferenceInformation":{"code":"12345678"},"orderInformation":{"billTo":{"country":"US","firstName":"John","lastName":"Deo","phoneNumber":"9321499232","address1":"900 Metro Center Blvd","postalCode":"48104-2201","locality":"Foster City","administrativeArea":"CA","email":"test@cybs.com"},"amountDetails":{"totalAmount":"200","currency":"usd"}},"paymentInformation":{"card":{"expirationYear":"2031","number":"4111111111111111","expirationMonth":"03","type":"001"}}}}}}},"/pts/v2/payments/{id}/voids":{"post":{"summary":"Void a Payment","description":"Include the payment ID in the POST request to cancel the payment.","tags":["void"],"operationId":"voidPayment","parameters":[{"name":"voidPaymentRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"comments":{"type":"string","description":"Comments"}}}},"example":{"clientReferenceInformation":{"code":"test_void"}}}},{"name":"id","in":"path","description":"The payment ID returned from a previous payment request.","required":true,"type":"string"}],"responses":{"201":{"description":"Successful response.","schema":{"title":"ptsV2PaymentsVoidsPost201Response","type":"object","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["VOIDED"]},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"voidAmountDetails":{"type":"object","properties":{"voidAmount":{"type":"string","description":"Total amount of the void."},"originalTransactionAmount":{"type":"string","description":"Amount of the original transaction."},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}}},"example":{"_links":{"self":{"href":"/pts/v2/voids/4963015122056179201545","method":"GET"}},"id":"4963015122056179201545","submitTimeUtc":"2017-06-01T071832Z","status":"VOIDED","clientReferenceInformation":{"code":"test_void"},"orderInformation":{"amountDetails":{"currency":"USD"}},"voidAmountDetails":{"currency":"usd","voidAmount":"102.21"}}}},"400":{"description":"Invalid request.","schema":{"title":"ptsV2PaymentsVoidsPost400Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_MERCHANT_CONFIGURATION","NOT_VOIDABLE"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"title":"ptsV2PaymentsVoidsPost502Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Void a Payment","value":{"clientReferenceInformation":{"code":"test_void"}}}}}},"/pts/v2/captures/{id}/voids":{"post":{"summary":"Void a Capture","description":"Include the capture ID in the POST request to cancel the capture.","tags":["void"],"operationId":"voidCapture","parameters":[{"name":"voidCaptureRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"comments":{"type":"string","description":"Comments"}}}},"example":{"clientReferenceInformation":{"code":"test_void"}}}},{"name":"id","in":"path","description":"The capture ID returned from a previous capture request.","required":true,"type":"string"}],"responses":{"201":{"description":"Successful response.","schema":{"title":"ptsV2CapturesVoidsPost201Response","type":"object","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["VOIDED"]},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"voidAmountDetails":{"type":"object","properties":{"voidAmount":{"type":"string","description":"Total amount of the void."},"originalTransactionAmount":{"type":"string","description":"Amount of the original transaction."},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}}},"example":{"_links":{"self":{"href":"/pts/v2/voids/4963015122056179201545","method":"GET"}},"id":"4963015122056179201545","submitTimeUtc":"2017-06-01T071832Z","status":"VOIDED","clientReferenceInformation":{"code":"test_void"},"orderInformation":{"amountDetails":{"currency":"USD"}},"voidAmountDetails":{"currency":"usd","voidAmount":"102.21"}}}},"400":{"description":"Invalid request.","schema":{"title":"ptsV2CapturesVoidsPost400Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_MERCHANT_CONFIGURATION","NOT_VOIDABLE"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"title":"ptsV2CapturesVoidsPost502Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Void a Capture","value":{"clientReferenceInformation":{"code":"test_void"}}}}}},"/pts/v2/refunds/{id}/voids":{"post":{"summary":"Void a Refund","description":"Include the refund ID in the POST request to cancel the refund.","tags":["void"],"operationId":"voidRefund","parameters":[{"name":"voidRefundRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"comments":{"type":"string","description":"Comments"}}}},"example":{"clientReferenceInformation":{"code":"test_void"}}}},{"name":"id","in":"path","description":"The refund ID returned from a previous refund request.","required":true,"type":"string"}],"responses":{"201":{"description":"Successful response.","schema":{"title":"ptsV2RefundsVoidsPost201Response","type":"object","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["VOIDED"]},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"voidAmountDetails":{"type":"object","properties":{"voidAmount":{"type":"string","description":"Total amount of the void."},"originalTransactionAmount":{"type":"string","description":"Amount of the original transaction."},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}}},"example":{"_links":{"self":{"href":"/pts/v2/voids/4963015122056179201545","method":"GET"}},"id":"4963015122056179201545","submitTimeUtc":"2017-06-01T071832Z","status":"VOIDED","clientReferenceInformation":{"code":"test_void"},"orderInformation":{"amountDetails":{"currency":"USD"}},"voidAmountDetails":{"currency":"usd","voidAmount":"102.21"}}}},"400":{"description":"Invalid request.","schema":{"title":"ptsV2RefundsVoidsPost400Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_MERCHANT_CONFIGURATION","NOT_VOIDABLE"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"title":"ptsV2RefundsVoidsPost502Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Void a Refund","value":{"clientReferenceInformation":{"code":"test_void"}}}}}},"/pts/v2/credits/{id}/voids":{"post":{"summary":"Void a Credit","description":"Include the credit ID in the POST request to cancel the credit.","tags":["Void"],"operationId":"voidCredit","parameters":[{"name":"voidCreditRequest","in":"body","required":true,"schema":{"type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"comments":{"type":"string","description":"Comments"}}}},"example":{"clientReferenceInformation":{"code":"test_void"}}}},{"name":"id","in":"path","description":"The credit ID returned from a previous credit request.","required":true,"type":"string"}],"responses":{"201":{"description":"Successful response.","schema":{"title":"ptsV2CreditsVoidsPost201Response","type":"object","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["VOIDED"]},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"voidAmountDetails":{"type":"object","properties":{"voidAmount":{"type":"string","description":"Total amount of the void."},"originalTransactionAmount":{"type":"string","description":"Amount of the original transaction."},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}}},"example":{"_links":{"self":{"href":"/pts/v2/voids/4963015122056179201545","method":"GET"}},"id":"4963015122056179201545","submitTimeUtc":"2017-06-01T071832Z","status":"VOIDED","clientReferenceInformation":{"code":"test_void"},"orderInformation":{"amountDetails":{"currency":"USD"}},"voidAmountDetails":{"currency":"usd","voidAmount":"102.21"}}}},"400":{"description":"Invalid request.","schema":{"title":"ptsV2CreditsVoidsPost400Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_MERCHANT_CONFIGURATION","NOT_VOIDABLE"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"title":"ptsV2CreditsVoidsPost502Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}},"x-example":{"example0":{"summary":"Void a Credit","value":{"clientReferenceInformation":{"code":"test_void"}}}}}},"/pts/v1/transaction-batches":{"get":{"summary":"Get a list of batch files processed through the Offline Transaction Submission Services","description":"Provide the search range","tags":["TransactionBatches"],"produces":["application/hal+json"],"parameters":[{"name":"startTime","in":"query","description":"Valid report Start Time in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd'T'HH:mm:ss.SSSZZ\n","required":true,"type":"string","format":"date-time"},{"name":"endTime","in":"query","description":"Valid report End Time in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd'T'HH:mm:ss.SSSZZ\n","required":true,"type":"string","format":"date-time"}],"x-example":{"example0":{"summary":"Get Transaction Batch files","value":{"clientReferenceInformation":{"code":"test_void"}}}},"responses":{"200":{"description":"OK","schema":{"title":"ptsV1TransactionBatchesGet200Response","type":"object","properties":{"transactionBatches":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier assigned to the batch file.","example":"psy8s1d","pattern":"^[a-zA-Z0-9_+-]*$","minLength":1,"maxLength":8},"uploadDate":{"type":"string","description":"Date when the batch template was update.","example":"2018-01-01"},"completionDate":{"type":"string","description":"The date when the batch template processing completed.","example":"2018-01-01"},"transactionCount":{"type":"integer","description":"Number of transactions in the transaction.","example":7534},"acceptedTransactionCount":{"type":"integer","description":"Number of transactions accepted.","example":50013},"rejectedTransactionCount":{"type":"string","description":"Number of transactions rejected.","example":2508},"status":{"type":"string","description":"The status of you batch template processing.","example":"Completed"}}}},"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"/pts/v1/transaction-batches"},"method":{"type":"string","example":"GET"}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"400":{"description":"Bad Request","schema":{"title":"ptsV1TransactionBatchesGet400Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid.\n"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above.\n"}}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"401":{"description":"Not Authorized","schema":{"title":"ptsV1TransactionBatchesGet401Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid.\n"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above.\n"}}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"403":{"description":"No Authenticated","schema":{"title":"ptsV1TransactionBatchesGet403Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid.\n"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above.\n"}}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"404":{"description":"No Reports Found","schema":{"title":"ptsV1TransactionBatchesGet404Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid.\n"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above.\n"}}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"500":{"description":"Bad Gateway","schema":{"title":"ptsV1TransactionBatchesGet500Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The reason of status"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above."}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}}}}},"/pts/v1/transaction-batches/{id}":{"get":{"summary":"Get an individual batch file Details processed through the Offline Transaction Submission Services","description":"Provide the search range","tags":["TransactionBatch"],"produces":["application/hal+json"],"parameters":[{"name":"id","in":"path","description":"The batch id assigned for the template.","required":true,"type":"string"}],"x-example":{"example0":{"summary":"Get Transaction Batch file by ID","value":{"clientReferenceInformation":{"code":"test_void"}}}},"responses":{"200":{"description":"OK","schema":{"title":"ptsV1TransactionBatchesIdGet200Response","allOf":[{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier assigned to the batch file.","example":"psy8s1d","pattern":"^[a-zA-Z0-9_+-]*$","minLength":1,"maxLength":8},"uploadDate":{"type":"string","description":"Date when the batch template was update.","example":"2018-01-01"},"completionDate":{"type":"string","description":"The date when the batch template processing completed.","example":"2018-01-01"},"transactionCount":{"type":"integer","description":"Number of transactions in the transaction.","example":7534},"acceptedTransactionCount":{"type":"integer","description":"Number of transactions accepted.","example":50013},"rejectedTransactionCount":{"type":"string","description":"Number of transactions rejected.","example":2508},"status":{"type":"string","description":"The status of you batch template processing.","example":"Completed"}}},{"type":"object","properties":{"_links":{"type":"object","properties":{"transactions":{"type":"array","items":{"type":"object","properties":{"href":{"type":"string","description":"Self link for this request","example":"v1/payments/5289798134206292501013"},"method":{"type":"string"}}}}}}}}]}},"400":{"description":"Bad Request","schema":{"title":"ptsV1TransactionBatchesIdGet400Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid.\n"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above.\n"}}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"401":{"description":"Not Authorized","schema":{"title":"ptsV1TransactionBatchesIdGet401Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid.\n"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above.\n"}}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"403":{"description":"No Authenticated","schema":{"title":"ptsV1TransactionBatchesIdGet403Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid.\n"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above.\n"}}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"404":{"description":"No Reports Found","schema":{"title":"ptsV1TransactionBatchesIdGet404Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid.\n"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above.\n"}}}}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}},"502":{"description":"Bad Gateway","schema":{"title":"ptsV1TransactionBatchesIdGet502Response","type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The reason of status"},"message":{"type":"string","description":"The detailed message related to the status and reason listed above."}}},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"}}}}}}},"/pts/v2/payouts/":{"post":{"summary":"Process a Payout","description":"Send funds from a selected funding source to a designated credit/debit card account or a prepaid card using\nan Original Credit Transaction (OCT).\n","operationId":"octCreatePayment","parameters":[{"name":"octCreatePaymentRequest","in":"body","required":true,"schema":{"title":"ptsV2PayoutsPostResponse","type":"object","properties":{"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"},"surcharge":{"type":"object","properties":{"amount":{"type":"string","maxLength":15,"description":"The surcharge amount is included in the total transaction amount but is passed in a separate field to the issuer\nand acquirer for tracking. The issuer can provide information about the surcharge amount to the customer.\n\n- Applicable only for CTV for Payouts.\n- CTV (<= 08)\n\nFor processor-specific information, see the surcharge_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the billing street address as it appears on the credit card issuer\u2019s records.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address1 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address2":{"type":"string","maxLength":60,"description":"Additional address information.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address2 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":50,"description":"City of the billing address.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_city field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the billing address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_state field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the billing address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_zip field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneType":{"type":"string","enum":["day","home","night","work"],"description":"Customer's phone number type.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nPossible Values - \n* day\n* home\n* night\n* work\n"}}}}},"merchantInformation":{"type":"object","properties":{"categoryCode":{"type":"integer","maximum":9999,"description":"Four-digit number that the payment card industry uses to classify merchants into market segments. Visa assigned\none or more of these values to your business when you started accepting Visa cards.\n\nIf you do not include this field in your request, CyberSource uses the value in your CyberSource account.\n\nFor processor-specific information, see the merchant_category_code field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"submitLocalDateTime":{"type":"string","maxLength":6,"description":"Time that the transaction was submitted in local time. The time is in hhmmss format.\n"},"vatRegistrationNumber":{"type":"string","maxLength":21,"description":"Your government-assigned tax identification number.\n\nFor CtV processors, the maximum length is 20.\n\nFor other processor-specific information, see the merchant_vat_registration_number field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"merchantDescriptor":{"type":"object","properties":{"name":{"type":"string","maxLength":23,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\nFor Payouts:\n* Paymentech (22)\n"},"locality":{"type":"string","maxLength":13,"description":"Merchant City. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":3,"description":"Merchant State. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"contact":{"type":"string","maxLength":14,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n* FDCCompass (13)\n* Paymentech (13)\n"}}}}},"recipientInformation":{"type":"object","properties":{"firstName":{"type":"string","maxLength":35,"description":"First name of recipient.\ncharacters.\n* CTV (14)\n* Paymentech (30)\n"},"middleInitial":{"type":"string","maxLength":1,"description":"Middle Initial of recipient. Required only for FDCCompass.\n"},"lastName":{"type":"string","maxLength":35,"description":"Last name of recipient.\ncharacters.\n* CTV (14)\n* Paymentech (30)\n"},"address1":{"type":"string","maxLength":50,"description":"Recipient address information. Required only for FDCCompass."},"locality":{"type":"string","maxLength":25,"description":"Recipient city. Required only for FDCCompass."},"administrativeArea":{"type":"string","maxLength":3,"description":"Recipient State. Required only for FDCCompass."},"country":{"type":"string","maxLength":2,"description":"Recipient country code. Required only for FDCCompass."},"postalCode":{"type":"string","maxLength":10,"description":"Recipient postal code. Required only for FDCCompass."},"phoneNumber":{"type":"string","maxLength":20,"description":"Recipient phone number. Required only for FDCCompass."},"dateOfBirth":{"type":"string","minLength":8,"maxLength":8,"description":"Recipient date of birth in YYYYMMDD format. Required only for FDCCompass."}}},"senderInformation":{"type":"object","properties":{"referenceNumber":{"type":"string","maxLength":19,"description":"Reference number generated by you that uniquely identifies the sender."},"account":{"type":"object","properties":{"fundsSource":{"type":"string","minLength":2,"maxLength":2,"description":"Source of funds. Possible values:\n\n Paymentech, CTV, FDC Compass:\n - 01: Credit card\n - 02: Debit card\n - 03: Prepaid card\n\n Paymentech, CTV -\n - 04: Cash\n - 05: Debit or deposit account that is not linked to a Visa card. Includes checking accounts, savings\n accounts, and proprietary debit or ATM cards.\n - 06: Credit account that is not linked to a Visa card. Includes credit cards and proprietary lines\n of credit.\n\n FDCCompass -\n - 04: Deposit Account\n\n**Funds Disbursement**\n\nThis value is most likely 05 to identify that the originator used a deposit account to fund the\ndisbursement.\n\n**Credit Card Bill Payment**\n\nThis value must be 02, 03, 04, or 05.\n"},"number":{"type":"string","maxLength":34,"description":"The account number of the entity funding the transaction. It is the sender\u2019s account number. It can\nbe a debit/credit card account number or bank account number.\n\n**Funds disbursements**\n\nThis field is optional.\n\n**All other transactions**\n\nThis field is required when the sender funds the transaction with a financial instrument, for example\ndebit card.\nLength:\n* FDCCompass (<= 19)\n* Paymentech (<= 16)\n"}}},"firstName":{"type":"string","maxLength":35,"description":"First name of sender (Optional).\n* CTV (14)\n* Paymentech (30)\n"},"middleInitial":{"type":"string","maxLength":1,"description":"Recipient middle initial (Optional).\n"},"lastName":{"type":"string","maxLength":35,"description":"Recipient last name (Optional).\n* CTV (14)\n* Paymentech (30)\n"},"name":{"type":"string","maxLength":24,"description":"Name of sender.\n\n**Funds Disbursement**\n\nThis value is the name of the originator sending the funds disbursement.\n* CTV, Paymentech (30)\n"},"address1":{"type":"string","maxLength":50,"description":"Street address of sender.\n\n**Funds Disbursement**\n\nThis value is the address of the originator sending the funds disbursement.\n"},"locality":{"type":"string","maxLength":25,"description":"City of sender.\n\n**Funds Disbursement**\n\nThis value is the city of the originator sending the funds disbursement.\n"},"administrativeArea":{"type":"string","maxLength":2,"description":"Sender\u2019s state. Use the State, Province, and Territory Codes for the United States and Canada.\n"},"countryCode":{"type":"string","maxLength":2,"description":"Country of sender. Use the ISO Standard Country Codes.\n* CTV (3)\n"},"postalCode":{"type":"string","maxLength":10,"description":"Sender\u2019s postal code. Required only for FDCCompass."},"phoneNumber":{"type":"string","maxLength":20,"description":"Sender\u2019s phone number. Required only for FDCCompass."},"dateOfBirth":{"type":"string","minLength":8,"maxLength":8,"description":"Sender\u2019s date of birth in YYYYMMDD format. Required only for FDCCompass."},"vatRegistrationNumber":{"type":"string","maxLength":13,"description":"Customer's government-assigned tax identification number.\n"}}},"processingInformation":{"type":"object","properties":{"businessApplicationId":{"type":"string","maxLength":2,"description":"Payouts transaction type.\n\nApplicable Processors: FDC Compass, Paymentech, CtV\n\nPossible values:\n\n**Credit Card Bill Payment**\n\n - **CP**: credit card bill payment\n\n**Funds Disbursement**\n\n - **FD**: funds disbursement\n - **GD**: government disbursement\n - **MD**: merchant disbursement\n\n**Money Transfer**\n\n - **AA**: account to account. Sender and receiver are same person.\n - **PP**: person to person. Sender and receiver are different.\n\n**Prepaid Load**\n\n - **TU**: top up\n"},"networkRoutingOrder":{"type":"string","maxLength":30,"description":"This field is optionally used by Push Payments Gateway participants (merchants and acquirers) to get the attributes for specified networks only.\nThe networks specified in this field must be a subset of the information provided during program enrollment. Refer to Sharing Group Code/Network Routing Order.\nNote: Supported only in US for domestic transactions involving Push Payments Gateway Service.\n\nVisaNet checks to determine if there are issuer routing preferences for any of the networks specified by the network routing order.\nIf an issuer preference exists for one of the specified debit networks, VisaNet makes a routing selection based on the issuer\u2019s preference. \nIf an issuer preference exists for more than one of the specified debit networks, or if no issuer preference exists, VisaNet makes a selection based on the acquirer\u2019s routing priorities. \n\nSee https://developer.visa.com/request_response_codes#network_id_and_sharing_group_code , under section 'Network ID and Sharing Group Code' on the left panel for available values\n"},"commerceIndicator":{"type":"string","maxLength":13,"description":"Type of transaction. Possible value for Fast Payments transactions:\n\n - internet\n"},"reconciliationId":{"type":"string","maxLength":60,"description":"Please check with Cybersource customer support to see if your merchant account is configured correctly so you\ncan include this field in your request.\n* For Payouts: max length for FDCCompass is String (22).\n"},"payoutsOptions":{"type":"object","properties":{"acquirerMerchantId":{"type":"string","maxLength":15,"description":"This field identifies the card acceptor for defining the point of service terminal in both local and interchange environments. An acquirer-assigned code identifying the card acceptor for the transaction. \nDepending on the acquirer and merchant billing and reporting requirements, the code can represent a merchant, a specific merchant location, or a specific merchant location terminal.\nAcquiring Institution Identification Code uniquely identifies the merchant.\nThe value from the original is required in any subsequent messages, including reversals, chargebacks, and representments.\n* Applicable only for CTV for Payouts.\n"},"acquirerBin":{"type":"string","maxLength":11,"description":"This code identifies the financial institution acting as the acquirer of this customer transaction. The acquirer is the member or system user that signed the merchant or ADM or dispensed cash. \nThis number is usually Visa-assigned.\n* Applicable only for CTV for Payouts.\n"},"retrievalReferenceNumber":{"type":"string","maxLength":12,"description":"This field contains a number that is used with other data elements as a key to identify and track all messages related to a given cardholder transaction; that is, to a given transaction set.\n* Applicable only for CTV for Payouts.\n"},"accountFundingReferenceId":{"type":"string","maxLength":15,"description":"Visa-generated transaction identifier (TID) that is unique for each original authorization and financial request.\n* Applicable only for CTV for Payouts.\n"}}}}},"paymentInformation":{"type":"object","properties":{"card":{"type":"object","properties":{"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"},"number":{"type":"string","maxLength":20,"description":"Customer\u2019s credit card number. Encoded Account Numbers when processing encoded account numbers, use this field\nfor the encoded account number.\n\nFor processor-specific information, see the customer_cc_number field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationMonth":{"type":"string","maxLength":2,"description":"Two-digit month in which the credit card expires. `Format: MM`. Possible values: 01 through 12.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 12.\n\nFor processor-specific information, see the customer_cc_expmo field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationYear":{"type":"string","maxLength":4,"description":"Four-digit year in which the credit card expires. `Format: YYYY`.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 2021.\n\nFor processor-specific information, see the customer_cc_expyr field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"sourceAccountType":{"type":"string","maxLength":2,"description":"Flag that specifies the type of account associated with the card. The cardholder provides this information\nduring the payment process. This field is required in the following cases.\n - Debit transactions on Cielo and Comercio Latino.\n - Transactions with Brazilian-issued cards on CyberSource through VisaNet.\n - Applicable only for CTV.\n \n**Note**\nCombo cards in Brazil contain credit and debit functionality in a single card. Visa systems use a credit bank\nidentification number (BIN) for this type of card. Using the BIN to determine whether a card is debit or\ncredit can cause transactions with these cards to be processed incorrectly. CyberSource strongly recommends\nthat you include this field for combo card transactions.\n\nPossible values include the following.\n\n - CHECKING: Checking account\n - CREDIT: Credit card account\n - SAVING: Saving account\n - LINE_OF_CREDIT: Line of credit\n - PREPAID: Prepaid card account\n - UNIVERSAL: Universal account\n"}}}}}},"example":{"clientReferenceInformation":{"code":"33557799"},"senderInformation":{"referenceNumber":"1234567890","address1":"900 Metro Center Blvd.900","countryCode":"US","locality":"Foster City","name":"Thomas Jefferson","administrativeArea":"CA","account":{"number":"1234567890123456789012345678901234","fundsSource":"01"}},"processingInformation":{"commerceIndicator":"internet","businessApplicationId":"FD","networkRoutingOrder":"ECG"},"payoutsOptions":{"retrievalReferenceNumber":"123456789012","acquirerBin":"567890124"},"reconciliationId":"1087488702VIAQNSPQ","orderInformation":{"amountDetails":{"totalAmount":"100.00","currency":"USD"}},"merchantInformation":{"merchantCategoryCode":"123","merchantDescriptor":{"country":"US","postalCode":"94440","locality":"FC","name":"Thomas","administrativeArea":"CA"}},"paymentInformation":{"card":{"expirationYear":"2025","number":"4111111111111111","expirationMonth":"12","type":"001","sourceAccountType":"CH"}},"recipientInformation":{"firstName":"John","lastName":"Doe","address1":"Paseo Padre Boulevard","locality":"Foster City","administrativeArea":"CA","postalCode":"94400","phoneNumber":"6504320556","dateOfBirth":"19801009","country":"US"}}}}],"tags":["Process a Payout"],"x-example":{"example0":{"summary":"Process a Payout","value":{"clientReferenceInformation":{"code":"33557799"},"senderInformation":{"referenceNumber":"1234567890","address1":"900 Metro Center Blvd.900","countryCode":"US","locality":"Foster City","name":"Company Name","administrativeArea":"CA","account":{"fundsSource":"05"}},"processingInformation":{"commerceIndicator":"internet","businessApplicationId":"FD"},"orderInformation":{"amountDetails":{"totalAmount":"100.00","currency":"USD"}},"merchantInformation":{"merchantDescriptor":{"country":"US","postalCode":"94440","locality":"FC","name":"Sending Company Name","administrativeArea":"CA"}},"paymentInformation":{"card":{"expirationYear":"2025","number":"4111111111111111","expirationMonth":"12","type":"001"}},"recipientInformation":{"firstName":"John","lastName":"Doe","address1":"Paseo Padre Boulevard","locality":"Foster City","administrativeArea":"CA","postalCode":"94400","phoneNumber":"6504320556","country":"US"}}}},"responses":{"201":{"description":"Successful response.","schema":{"title":"ptsV2PayoutsPost201Response","allOf":[{"type":"object","properties":{"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}},"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["ACCEPTED","DECLINED"]},"reconciliationId":{"type":"string","maxLength":25,"description":"Cybersource or merchant generated transaction reference number. This is sent to the processor and is echoed back in the response to the merchant. This is\nThis value is used for reconciliation purposes.\n"},"statusInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The reason of the status.\n","enum":["SUCCESS","CONTACT_PROCESSOR"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above. Possible value is:\n\n - Transaction was successful.\n - You must call the issuing bank to proceed with the transaction.\n"}}}}},{"type":"object","properties":{"errorInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The reason of the status.\n","enum":["EXPIRED_CARD","PROCESSOR_DECLINED","STOLEN_LOST_CARD","UNAUTHORIZED_CARD","CVN_NOT_MATCH","INVALID_CVN","BLACKLISTED_CUSTOMER","INVALID_ACCOUNT","GENERAL_DECLINE","RISK_CONTROL_DECLINE","PROCESSOR_RISK_CONTROL_DECLINE"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"properties":{"name":{"type":"string","maxLength":23,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\nFor Payouts:\n* Paymentech (22)\n"},"locality":{"type":"string","maxLength":13,"description":"Merchant City. For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}}}},"orderInformation":{"type":"object","properties":{"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"},"settlementAmount":{"type":"string","maxLength":12,"description":"This is a multicurrency field. It contains the transaction amount (field 4), converted to the Currency used to bill the cardholder\u2019s account.\n"},"settlementCurrency":{"type":"string","maxLength":3,"description":"This is a multicurrency-only field. It contains a 3-digit numeric code that identifies the currency used by the issuer to bill the cardholder's account.\n"}}}}},"processorInformation":{"type":"object","properties":{"approvalCode":{"type":"string","maxLength":6,"description":"Issuer-generated approval code for the transaction."},"responseCode":{"type":"string","maxLength":10,"description":"Transaction status from the processor."},"transactionId":{"type":"string","maxLength":15,"description":"Network transaction identifier (TID). This value can be used to identify a specific transaction when\nyou are discussing the transaction with your processor.\n"},"systemTraceAuditNumber":{"type":"string","maxLength":6,"description":"This field is returned only for **American Express Direct** and **CyberSource through VisaNet**.\n\n**American Express Direct**\n\nSystem trace audit number (STAN). This value identifies the transaction and is useful when investigating a\nchargeback dispute.\n\n**CyberSource through VisaNet**\n\nSystem trace number that must be printed on the customer\u2019s receipt.\n"},"responseCodeSource":{"type":"string","maxLength":1,"description":"Used by Visa only and contains the response source/reason code that identifies the source of the response decision.\n"}}},"recipientInformation":{"type":"object","properties":{"card":{"type":"object","properties":{"balance":{"type":"string","maxLength":12,"description":"This field shows the available balance in the prepaid account. \nAcquirers always receive the available balance in the transaction currency.\n"},"currency":{"type":"string","maxLength":3,"description":"This is a multicurrency-only field. It contains a 3-digit numeric code that identifies the currency used by the issuer.\n"}}}}}}}],"example":{"_links":{"self":{"href":"/pts/v2/payouts/5287556536256000401540","method":"GET"}},"clientReferenceInformation":{"code":"1528755653559"},"id":"5287556536256000401540","orderInformation":{"amountDetails":{"totalAmount":"100.00","currency":"USD"}},"processorInformation":{"systemTraceAuditNumber":"897596","approvalCode":"831000","transactionId":"016153570198200","responseCode":"00","responseCodeSource":"5"},"reconciliationId":"1087488702VIAQNSPQ","status":"ACCEPTED","submitTimeUtc":"2018-06-11T222054Z"}}},"400":{"description":"Invalid request.","schema":{"title":"ptsV2PayoutsPost400Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction."},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_MERCHANT_CONFIGURATION","INVALID_AMOUNT","DEBIT_CARD_USEAGE_EXCEEDD_LIMIT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above. Possible value is:\n\n - Your aggregator or acquirer is not accepting transactions from you at this time.\n - Your aggregator or acquirer is not accepting this transaction.\n - CyberSource declined the request because the credit card has expired. You might also receive this value if\n the expiration date you provided does not match the date the issuing bank has on file.\n - The bank declined the transaction.\n - The merchant reference number for this authorization request matches the merchant reference number of\n another authorization request that you sent within the past 15 minutes. Resend the request with a unique\n merchant reference number.\n - The credit card number did not pass CyberSource basic checks.\n - Data provided is not consistent with the request. For example, you requested a product with negative cost.\n - The request is missing a required field.\n"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"title":"ptsV2PayoutsPost502Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}}}},"/reporting/v3/notification-of-changes":{"get":{"tags":["NotificationOfChanges"],"summary":"Get Notification Of Changes","description":"Notification of Change Report","operationId":"getNotificationOfChangeReport","produces":["application/hal+json"],"parameters":[{"name":"startTime","in":"query","description":"Valid report Start Time in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd'T'HH:mm:ssXXX\n","required":true,"type":"string","format":"date-time"},{"name":"endTime","in":"query","description":"Valid report End Time in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd'T'HH:mm:ssXXX\n","required":true,"type":"string","format":"date-time"}],"x-example":{"example0":{"summary":"Get Notification Of Changes","value":[]}},"responses":{"200":{"description":"Ok","schema":{"title":"reportingV3NotificationofChangesGet200Response","type":"object","properties":{"notificationOfChanges":{"type":"array","description":"List of Notification Of Change Info values","items":{"type":"object","properties":{"merchantReferenceNumber":{"type":"string","example":"TC30877-10","description":"Merchant Reference Number"},"transactionReferenceNumber":{"type":"string","example":"55563","description":"Transaction Reference Number"},"time":{"type":"string","example":"2017-10-01T10:10:10+05:00","format":"date-time","description":"Notification Of Change Date(ISO 8601 Extended)"},"code":{"type":"string","example":"TC30877-10","description":"Merchant Reference Number"},"accountType":{"type":"string","example":"Checking Account","description":"Account Type"},"routingNumber":{"type":"string","example":"123456789","description":"Routing Number"},"accountNumber":{"type":"string","example":"############1234","description":"Account Number"},"consumerName":{"type":"string","example":"Consumer Name","description":"Consumer Name"}},"description":"Notification Of Change"}}}}},"400":{"description":"Invalid request","schema":{"title":"reportingV3NotificationofChangesGet400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"VALIDATION_ERROR","correlationId":null,"detail":null,"fields":[{"path":"startDate","message":"Start date should not precede 18 months from current time in GMT","localizationKey":null}],"localizationKey":"cybsapi.validation.errors","message":"Field validation errors"}}},"401":{"description":"Unauthorized. Token provided is no more valid."},"404":{"description":"Report not found","schema":{"title":"reportingV3NotificationofChangesGet404Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"RESOURCE_NOTFOUND","correlationId":null,"detail":"The requested resource is not found. Please try again later.","localizationKey":"cybsapi.resource.notfound","message":"No results found for the given dates"}}},"500":{"description":"Internal Server Error","schema":{"title":"reportingV3NotificationofChangesGet500Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"SERVER_ERROR","correlationId":null,"detail":"Internal Server Error. Please contact the customer support.","localizationKey":"cybsapi.server.error","message":"Error encountered while processing request"}}}}}},"/reporting/v3/purchase-refund-details":{"get":{"tags":["PurchaseAndRefundDetails"],"summary":"Get Purchase and Refund details","description":"Purchase And Refund Details Description","operationId":"getPurchaseAndRefundDetails","produces":["application/hal+json"],"parameters":[{"name":"startTime","in":"query","description":"Valid report Start Time in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd'T'HH:mm:ssXXX\n","required":true,"type":"string","format":"date-time"},{"name":"endTime","in":"query","description":"Valid report End Time in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd'T'HH:mm:ssXXX\n","required":true,"type":"string","format":"date-time"},{"name":"organizationId","in":"query","description":"Valid Cybersource Organization Id","pattern":"[a-zA-Z0-9-_]+","required":false,"type":"string","minLength":1,"maxLength":32},{"name":"paymentSubtype","in":"query","description":"Payment Subtypes.\n - **ALL**: All Payment Subtypes\n - **VI** : Visa\n - **MC** : Master Card\n - **AX** : American Express\n - **DI** : Discover\n - **DP** : Pinless Debit\n","required":false,"type":"string","default":"ALL","enum":["ALL","VI","MC","AX","DI","DP"]},{"name":"viewBy","in":"query","description":"View results by Request Date or Submission Date.\n - **requestDate** : Request Date\n - **submissionDate**: Submission Date\n","required":false,"type":"string","default":"requestDate","enum":["requestDate","submissionDate"]},{"name":"groupName","in":"query","description":"Valid CyberSource Group Name.User can define groups using CBAPI and Group Management Module in EBC2. Groups are collection of organizationIds","required":false,"type":"string"},{"name":"offset","in":"query","description":"Offset of the Purchase and Refund Results.","required":false,"type":"integer","format":"int32"},{"name":"limit","in":"query","description":"Results count per page. Range(1-2000)","required":false,"type":"integer","minimum":1,"maximum":2000,"default":2000,"format":"int32"}],"x-example":{"example0":{"summary":"Get Purchase and Refund details","value":[]}},"responses":{"200":{"description":"Ok","schema":{"title":"reportingV3PurchaseRefundDetailsGet200Response","allOf":[{"type":"object","properties":{"offset":{"type":"integer"},"limit":{"type":"integer"},"pageResults":{"type":"integer"}}},{"type":"object","description":"PurchaseAndRefundDetails","properties":{"requestDetails":{"type":"array","description":"List of Request Info values","items":{"type":"object","properties":{"requestId":{"type":"string","example":"12345678901234567890123456","description":"An unique identification number assigned by CyberSource to identify the submitted request."},"cybersourceMerchantId":{"type":"string","example":"Cybersource Merchant Id","description":"Cybersource Merchant Id"},"processorMerchantId":{"type":"string","example":"Processor Merchant Id","description":"Cybersource Processor Merchant Id"},"groupName":{"type":"string","example":"996411990498708810001","description":"Group Name"},"transactionReferenceNumber":{"type":"string","example":"RZ3J9WCS9J33","description":"Transaction Reference Number"},"merchantReferenceNumber":{"type":"string","example":"47882339","description":"Merchant Reference Number"}},"description":"Request Info Section"}},"settlements":{"type":"array","description":"List of Settlement Info values","items":{"type":"object","properties":{"requestId":{"type":"string","example":"12345678901234567890123456","description":"An unique identification number assigned by CyberSource to identify the submitted request."},"transactionType":{"type":"string","example":"Purchases","description":"Transaction Type"},"submissionTime":{"type":"string","example":"2017-10-01T10:10:10+05:00","description":"Submission Date","format":"date-time"},"amount":{"type":"string","example":"23.00","description":"Amount"},"currencyCode":{"type":"string","example":"USD","description":"Valid ISO 4217 ALPHA-3 currency code"},"paymentMethod":{"type":"string","example":"VISA","description":"payment method"},"walletType":{"type":"string","example":"V.me","description":"Solution Type (Wallet)"},"paymentType":{"type":"string","example":"credit card","description":"Payment Type"},"accountSuffix":{"type":"string","example":"0004","description":"Account Suffix"},"cybersourceBatchTime":{"type":"string","example":"2017-10-01T10:10:10+05:00","description":"Cybersource Batch Time","format":"date-time"},"cybersourceBatchId":{"type":"string","example":"123123123123123","description":"Cybersource Batch Id"},"cardType":{"type":"string","example":"null","description":"Card Type"},"debitNetwork":{"type":"string","example":"","description":"Debit Network"}}}},"authorizations":{"type":"array","description":"List of Authorization Info values","items":{"type":"object","properties":{"requestId":{"type":"string","example":"12345678901234567890123456","description":"An unique identification number assigned by CyberSource to identify the submitted request."},"transactionReferenceNumber":{"type":"string","example":"RZ3J9WCS9J27","description":"Authorization Transaction Reference Number"},"time":{"type":"string","example":"2017-10-01T10:10:10+05:00","description":"Authorization Date","format":"date-time"},"authorizationRequestId":{"type":"string","example":"12345678901234567890123459","description":"Authorization Request Id"},"amount":{"type":"string","example":"2.50","description":"Authorization Amount"},"currencyCode":{"type":"string","example":"USD","description":"Valid ISO 4217 ALPHA-3 currency code"},"code":{"type":"string","example":"160780","description":"Authorization Code"},"rcode":{"type":"string","example":"1","description":"Authorization RCode"}},"description":"Authorization Info Values"}},"feeAndFundingDetails":{"type":"array","description":"List of Fee Funding Info values","items":{"type":"object","properties":{"requestId":{"type":"string","maxLength":26,"example":"12345678901234567890123456","description":"An unique identification number assigned by CyberSource to identify the submitted request."},"interchangePerItemFee":{"type":"string","example":"2.7","description":"interchange Per Item Fee"},"discountPercentage":{"type":"string","example":"2.39","description":"Discount Percentage"},"discountAmount":{"type":"string","example":"0.429","description":"Discount Amount"},"discountPerItemFee":{"type":"string","example":"0.002","description":"Discount Per Item Fee"},"totalFee":{"type":"string","example":"0.429","description":"Total Fee"},"feeCurrency":{"type":"string","example":"1","description":"Fee Currency"},"duesAssessments":{"type":"string","example":"0","description":"Dues Assessments"},"fundingAmount":{"type":"string","example":"2.50","description":"Funding Amount"},"fundingCurrency":{"type":"string","example":"USD","description":"Funding Currency (ISO 4217)"}},"description":"Fee Funding Section"}},"others":{"type":"array","description":"List of Other Info values","items":{"type":"object","properties":{"requestId":{"type":"string","maxLength":26,"example":"12345678901234567890123456","description":"An unique identification number assigned by CyberSource to identify the submitted request."},"merchantData1":{"type":"string","example":"Merchant Defined Data","description":"Merchant Defined Data"},"merchantData2":{"type":"string","example":"Merchant Defined Data","description":"Merchant Defined Data"},"merchantData3":{"type":"string","example":"Merchant Defined Data","description":"Merchant Defined Data"},"merchantData4":{"type":"string","example":"Merchant Defined Data","description":"Merchant Defined Data"},"firstName":{"type":"string","example":"First Name","description":"First Name"},"lastName":{"type":"string","example":"Last Name","description":"Last Name"}},"description":"Other Merchant Details Values."}},"settlementStatuses":{"type":"array","description":"List of Settlement Status Info values","items":{"type":"object","properties":{"requestId":{"type":"string","maxLength":26,"example":"12345678901234567890123456","description":"An unique identification number assigned by CyberSource to identify the submitted request."},"status":{"type":"string","example":"Settlement Status","description":"Settlement Status"},"settlementTime":{"type":"string","example":"2017-10-01T10:10:10+05:00","format":"date-time","description":"Settlement Date"},"reasonCode":{"example":"reasonCode","type":"string","description":"ReasonCode"},"errorText":{"example":"errorText","type":"string","description":"errorText"}},"description":"Settlement Status Section Values."}}}}]}},"400":{"description":"Invalid request","schema":{"title":"reportingV3PurchaseRefundDetailsGet400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"VALIDATION_ERROR","correlationId":null,"detail":null,"fields":[{"path":"startDate","message":"Start date should not precede 18 months from current time in GMT","localizationKey":null}],"localizationKey":"cybsapi.validation.errors","message":"Field validation errors"}}},"401":{"description":"Ok","schema":{"title":"reportingV3PurchaseRefundDetailsGet401Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"VALIDATION_ERROR","correlationId":null,"detail":null,"fields":[{"path":"organizationId","message":"Organization doesn't has access to Purchase & Refund Details Search","localizationKey":null}],"localizationKey":"cybsapi.validation.errors","message":"Field validation errors"}}},"404":{"description":"Report not found","schema":{"title":"reportingV3PurchaseRefundDetailsGet404Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"RESOURCE_NOTFOUND","correlationId":null,"detail":"The requested resource is not found. Please try again later.","localizationKey":"cybsapi.resource.notfound","message":"Purchase and Refund Details not found for requested input values"}}},"500":{"description":"Internal Server Error","schema":{"title":"reportingV3PurchaseRefundDetailsGet500Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"SERVER_ERROR","correlationId":null,"detail":"Internal Server Error. Please contact the customer support.","localizationKey":"cybsapi.server.error","message":"Error encountered while processing request"}}}}}},"/reporting/v3/report-definitions":{"get":{"tags":["ReportDefinitions"],"summary":"Get reporting resource information","description":"","operationId":"getResourceV2Info","produces":["application/hal+json"],"parameters":[{"name":"organizationId","in":"query","description":"Valid Cybersource Organization Id","pattern":"[a-zA-Z0-9-_]+","required":false,"type":"string","minLength":1,"maxLength":32}],"x-example":{"example0":{"summary":"Get reporting resource information","value":[]}},"responses":{"200":{"description":"Ok","schema":{"title":"reportingV3ReportDefinitionsGet200Response","type":"object","properties":{"reportDefinitions":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"reportDefinitionId":{"type":"integer","format":"int32"},"reportDefintionName":{"type":"string"},"supportedFormats":{"type":"array","uniqueItems":true,"items":{"type":"string","enum":["application/xml","text/csv"]}},"description":{"type":"string"}}}}}}},"400":{"description":"Invalid request","schema":{"title":"reportingV3ReportDefinitionsGet400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"Report not found"}}}},"/reporting/v3/report-definitions/{reportDefinitionName}":{"get":{"tags":["ReportDefinitions"],"summary":"Get a single report definition information","description":"The report definition name must be used as path parameter exclusive of each other","operationId":"getResourceInfoByReportDefinition","produces":["application/hal+json"],"parameters":[{"name":"reportDefinitionName","in":"path","description":"Name of the Report definition to retrieve","required":true,"type":"string"},{"name":"organizationId","in":"query","description":"Valid Cybersource Organization Id","pattern":"[a-zA-Z0-9-_]+","required":false,"type":"string","minLength":1,"maxLength":32}],"x-example":{"example0":{"summary":"Get a single report definition information","value":[]}},"responses":{"200":{"description":"Ok","schema":{"title":"reportingV3ReportDefinitionsNameGet200Response","type":"object","properties":{"type":{"type":"string"},"reportDefinitionId":{"type":"integer","format":"int32"},"reportDefintionName":{"type":"string"},"attributes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"filterType":{"type":"string"},"default":{"type":"boolean"},"required":{"type":"boolean"},"supportedType":{"type":"string"}}}},"supportedFormats":{"type":"array","uniqueItems":true,"items":{"type":"string","enum":["application/xml","text/csv"]}},"description":{"type":"string"}}}},"400":{"description":"Invalid request","schema":{"title":"reportingV3ReportDefinitionsNameGet400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"Report not found"}}}},"/reporting/v3/report-subscriptions":{"get":{"tags":["ReportSubscriptions"],"summary":"Retrieve all subscriptions by organization","description":"","operationId":"getAllSubscriptions","produces":["application/hal+json"],"x-example":{"example0":{"summary":"Retrieve all subscriptions by organization","value":[]}},"responses":{"200":{"description":"Ok","schema":{"title":"reportingV3ReportSubscriptionsGet200Response","type":"object","properties":{"subscriptions":{"type":"array","items":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization Id"},"reportDefinitionId":{"type":"string","description":"Report Definition Id"},"reportDefinitionName":{"type":"string","description":"Report Definition"},"reportMimeType":{"type":"string","example":"application/xml","description":"Report Format","enum":["application/xml","text/csv"]},"reportFrequency":{"type":"string","example":"DAILY","description":"Report Frequency","enum":["DAILY","WEEKLY","MONTHLY"]},"reportName":{"type":"string","description":"Report Name","example":"My Transaction Request Detail Report"},"timezone":{"type":"string","description":"Time Zone","example":"America/Chicago"},"startTime":{"type":"string","description":"Start Time","format":"date-time","example":"2017-10-01T10:10:10+05:00"},"startDay":{"type":"integer","format":"int32","description":"Start Day","example":1},"reportFields":{"type":"array","example":["Request.RequestID","Request.TransactionDate","Request.MerchantID"],"description":"List of all fields String values","items":{"type":"string"}},"reportFilters":{"type":"array","items":{"type":"string"},"example":["ics_auth","ics_bill"],"description":"List of filters to apply","additionalProperties":{"type":"array","items":{"type":"string"}}},"reportPreferences":{"type":"object","properties":{"signedAmounts":{"type":"boolean","description":"Indicator to determine whether negative sign infron of amount for all refunded transaction"},"fieldNameConvention":{"type":"string","description":"Specify the field naming convention to be followed in reports (applicable to only csv report formats","enum":["SOAPI","SCMP"]}},"description":"Report Preferences"},"selectedMerchantGroupName":{"type":"string","example":"testGroup","description":"Selected name of the group."}},"description":"Subscription Details"}}}}},"400":{"description":"Invalid request","schema":{"title":"reportingV3ReportSubscriptionsGet400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"Subscriptions not found"}}}},"/reporting/v3/report-subscriptions/{reportName}":{"get":{"tags":["ReportSubscriptions"],"summary":"Retrieve subscription for a report name by organization","description":"","operationId":"getSubscription","produces":["application/hal+json"],"parameters":[{"name":"reportName","in":"path","description":"Name of the Report to Retrieve","required":true,"type":"string","maxLength":80,"minLength":1,"pattern":"[a-zA-Z0-9-_+]+"}],"x-example":{"example0":{"summary":"Retrieve subscription for a report name by organization","value":[]}},"responses":{"200":{"description":"Ok","schema":{"title":"reportingV3ReportsSbscriptionsNameGet200Response","type":"object","properties":{"organizationId":{"type":"string","description":"Organization Id"},"reportDefinitionId":{"type":"string","description":"Report Definition Id"},"reportDefinitionName":{"type":"string","description":"Report Definition"},"reportMimeType":{"type":"string","example":"application/xml","description":"Report Format","enum":["application/xml","text/csv"]},"reportFrequency":{"type":"string","example":"DAILY","description":"Report Frequency","enum":["DAILY","WEEKLY","MONTHLY"]},"reportName":{"type":"string","description":"Report Name","example":"My Transaction Request Detail Report"},"timezone":{"type":"string","description":"Time Zone","example":"America/Chicago"},"startTime":{"type":"string","description":"Start Time","format":"date-time","example":"2017-10-01T10:10:10+05:00"},"startDay":{"type":"integer","format":"int32","description":"Start Day","example":1},"reportFields":{"type":"array","example":["Request.RequestID","Request.TransactionDate","Request.MerchantID"],"description":"List of all fields String values","items":{"type":"string"}},"reportFilters":{"type":"array","items":{"type":"string"},"example":["ics_auth","ics_bill"],"description":"List of filters to apply","additionalProperties":{"type":"array","items":{"type":"string"}}},"reportPreferences":{"type":"object","properties":{"signedAmounts":{"type":"boolean","description":"Indicator to determine whether negative sign infron of amount for all refunded transaction"},"fieldNameConvention":{"type":"string","description":"Specify the field naming convention to be followed in reports (applicable to only csv report formats","enum":["SOAPI","SCMP"]}},"description":"Report Preferences"},"selectedMerchantGroupName":{"type":"string","example":"testGroup","description":"Selected name of the group."}},"description":"Subscription Details"}},"400":{"description":"Invalid request","schema":{"title":"reportingV3ReportSubscriptionsNameGet400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"Subscription not found"}}},"put":{"tags":["ReportSubscriptions"],"summary":"Create Report Subscription for a report name by organization","description":"","operationId":"createSubscription","consumes":["application/json"],"produces":["application/hal+json"],"parameters":[{"name":"reportName","in":"path","description":"Name of the Report to Create","required":true,"type":"string"},{"in":"body","name":"requestBody","description":"Report subscription request payload","required":true,"schema":{"type":"object","required":["reportDefinitionName","reportFields","reportName"],"properties":{"organizationId":{"type":"string","pattern":"[a-zA-Z0-9-_]+"},"reportDefinitionName":{"type":"string","minLength":1,"maxLength":80,"pattern":"[a-zA-Z0-9-]+"},"reportFields":{"type":"array","items":{"type":"string"}},"reportMimeType":{"type":"string","example":"application/xml","enum":["application/xml","text/csv"]},"reportFrequency":{"type":"string"},"reportName":{"type":"string","minLength":1,"maxLength":128,"pattern":"[a-zA-Z0-9-_ ]+"},"timezone":{"type":"string","example":"America/Chicago"},"startTime":{"type":"string","format":"date-time","example":"2017-10-01T10:10:10+05:00"},"startDay":{"type":"integer","minimum":1,"maximum":7},"reportFilters":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"reportPreferences":{"type":"object","properties":{"signedAmounts":{"type":"boolean","description":"Indicator to determine whether negative sign infron of amount for all refunded transaction"},"fieldNameConvention":{"type":"string","description":"Specify the field naming convention to be followed in reports (applicable to only csv report formats","enum":["SOAPI","SCMP"]}},"description":"Report Preferences"},"selectedMerchantGroupName":{"type":"string","pattern":"[0-9]*"}}}}],"x-example":{"example0":{"summary":"","value":{"reportDefinitionName":"TransactionRequestClass","reportFields":["Request.RequestID","Request.TransactionDate","Request.MerchantID"],"reportMimeType":"application/xml","reportFrequency":"DAILY","timezone":"America/Chicago","startTime":"0900","startDay":1,"reportFilters":[],"reportPreferences":{"signedAmounts":false,"supportEmailAddresses":null,"additionalEmailAddresses":null},"selectedMerchantGroupName":null,"selectedOrganizationId":null,"organizationId":"uday_wf"}}},"responses":{"200":{"description":"Ok"},"304":{"description":"NOT MODIFIED"},"400":{"description":"Invalid request","schema":{"title":"reportingV3ReportSubscriptionsNamePut400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}}}},"delete":{"tags":["ReportSubscriptions"],"summary":"Delete subscription of a report name by organization","description":"","operationId":"deleteSubscription","produces":["application/hal+json"],"parameters":[{"name":"reportName","in":"path","description":"Name of the Report to Delete","required":true,"type":"string","maxLength":80,"minLength":1,"pattern":"[a-zA-Z0-9-_+]+"}],"x-example":{"example0":{"summary":"Delete subscription of a report name by organization","value":[]}},"responses":{"200":{"description":"Ok"},"400":{"description":"Invalid request","schema":{"title":"reportingV3ReportSubscriptionsNameDelete400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"Subscription not found","schema":{"title":"reportingV3ReportSubscriptionsnameDelete404Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}}}}},"/reporting/v3/reports":{"get":{"tags":["Reports"],"summary":"Retrieve available reports","description":"Retrieve list of available reports","operationId":"searchReports","produces":["application/hal+json"],"parameters":[{"name":"organizationId","in":"query","description":"Valid Cybersource Organization Id","pattern":"[a-zA-Z0-9-_]+","required":false,"type":"string","minLength":1,"maxLength":32},{"name":"startTime","in":"query","description":"Valid report Start Time in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd'T'HH:mm:ssXXX\n","required":true,"type":"string","format":"date-time"},{"name":"endTime","in":"query","description":"Valid report End Time in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd'T'HH:mm:ssXXX\n","required":true,"type":"string","format":"date-time"},{"name":"timeQueryType","in":"query","description":"Specify time you woud like to search","required":true,"type":"string","enum":["reportTimeFrame","executedTime"]},{"name":"reportMimeType","in":"query","description":"Valid Report Format","required":false,"type":"string","enum":["application/xml","text/csv"]},{"name":"reportFrequency","in":"query","description":"Valid Report Frequency","required":false,"type":"string","enum":["DAILY","WEEKLY","MONTHLY","ADHOC"]},{"name":"reportName","in":"query","description":"Valid Report Name","required":false,"type":"string"},{"name":"reportDefinitionId","in":"query","description":"Valid Report Definition Id","required":false,"type":"integer","format":"int32"},{"name":"reportStatus","in":"query","description":"Valid Report Status","required":false,"type":"string","enum":["COMPLETED","PENDING","QUEUED","RUNNING","ERROR","NO_DATA"]}],"x-example":{"example0":{"summary":"Retrieve available reports","value":[]}},"responses":{"200":{"description":"OK","schema":{"title":"reportingV3ReportsGet200Response","type":"object","properties":{"reports":{"type":"array","items":{"type":"object","properties":{"reportDefinitionId":{"type":"string","description":"Unique Report Identifier of each report type","example":"210"},"reportName":{"type":"string","description":"Name of the report specified by merchant while creating the report","example":"My Transaction Request Detail Report"},"reportMimeType":{"type":"string","example":"application/xml","description":"Format of the report to get generated","enum":["application/xml","text/csv"]},"reportFrequency":{"type":"string","example":"DAILY","description":"Frequency of the report to get generated","enum":["DAILY","WEEKLY","MONTHLY","ADHOC"]},"status":{"type":"string","description":"Status of the report","enum":["COMPLETED","PENDING","QUEUED","RUNNING","ERROR","NO_DATA"]},"reportStartTime":{"type":"string","format":"date-time","example":"2017-10-01T10:10:10+05:00","description":"Specifies the report start time in ISO 8601 format"},"reportEndTime":{"type":"string","format":"date-time","example":"2017-10-02T10:10:10+05:00","description":"Specifies the report end time in ISO 8601 format"},"timezone":{"type":"string","example":"America/Chicago","description":"Time Zone"},"reportId":{"type":"string","example":"6d9cb5b6-0e97-2d03-e053-7cb8d30af52e","description":"Unique identifier generated for every reports"},"organizationId":{"type":"string","example":"Test_MerchantId","description":"CyberSource Merchant Id"},"queuedTime":{"type":"string","format":"date-time","example":"2017-10-03T10:10:10+05:00","description":"Specifies the time of the report in queued in ISO 8601 format"},"reportGeneratingTime":{"type":"string","format":"date-time","example":"2017-10-03T10:10:10+05:00","description":"Specifies the time of the report started to generate in ISO 8601 format"},"reportCompletedTime":{"type":"string","format":"date-time","example":"2017-10-03T10:10:10+05:00","description":"Specifies the time of the report completed the generation in ISO 8601 format"},"selectedMerchantGroupName":{"type":"string","example":"myGroup","description":"Selected name of the group"}},"description":"Report Search Result Bean"}}}}},"400":{"description":"Invalid Request","schema":{"title":"reportingV3ReportsGet400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"No Reports Found"}}},"post":{"tags":["Reports"],"summary":"Create Adhoc Report","description":"Create one time report","operationId":"createReport","consumes":["application/json"],"produces":["application/hal+json"],"parameters":[{"in":"body","name":"requestBody","description":"Report subscription request payload","required":true,"schema":{"type":"object","properties":{"organizationId":{"type":"string","description":"Valid CyberSource Organization Id","pattern":"[a-zA-Z0-9-_]+","example":"Test_Merchatnt_id"},"reportDefinitionName":{"type":"string","minLength":1,"maxLength":80,"pattern":"[a-zA-Z0-9-]+","example":"TransactionRequestClass"},"reportFields":{"type":"array","items":{"type":"string"},"description":"List of fields which needs to get included in a report","example":["Request.RequestID","Request.TransactionDate","Request.MerchantID"]},"reportMimeType":{"type":"string","description":" Format of the report","example":"application/xml","enum":["application/xml","text/csv"]},"reportName":{"type":"string","minLength":1,"maxLength":128,"pattern":"[a-zA-Z0-9-_ ]+","description":"Name of the report","example":"My Transaction Request report"},"timezone":{"type":"string","description":"Timezone of the report","example":"America/Chicago"},"reportStartTime":{"type":"string","format":"date-time","description":"Start time of the report","example":"2017-10-01T10:10:10+05:00"},"reportEndTime":{"type":"string","format":"date-time","description":"End time of the report","example":"2017-10-02T10:10:10+05:00"},"reportFilters":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},"reportPreferences":{"type":"object","properties":{"signedAmounts":{"type":"boolean","description":"Indicator to determine whether negative sign infron of amount for all refunded transaction"},"fieldNameConvention":{"type":"string","description":"Specify the field naming convention to be followed in reports (applicable to only csv report formats","enum":["SOAPI","SCMP"]}},"description":"Report Preferences"},"selectedMerchantGroupName":{"type":"string","pattern":"[0-9]*","description":"Specifies the group name","example":"myGroup"}}}}],"x-example":{"example0":{"summary":"Create Adhoc Report","value":{"reportDefinitionName":"ChargebackAndRetrievalDetailClass","timezone":"GMT","reportMimeType":"text/csv","reportName":"TRR_133","reportStartTime":"2017-11-22T12:00:00+05:00","reportEndTime":"2017-11-23T12:00:00+05:00","reportFilters":{"Application.Name":[]},"reportPreferences":{"signedAmounts":"true","fieldNameConvention":"SOAPI"},"reportFields":["PaymentData.AuthorizationType","PaymentData.AuthorizationCode","PaymentData.AVSResult","PaymentData.CurrencyCode","PaymentData.AVSResultMapped","PaymentData.CVResult","PaymentData.ProcessorResponseCode","PaymentData.NumberOfInstallments","PaymentData.ACHVerificationResult","PaymentData.ACHVerificationResultMapped","PaymentData.BalanceAmount","PaymentData.BalanceCurrencyCode","PaymentData.RequestedAmount","PaymentData.RequestedAmountCurrencyCode","PaymentData.EVEmail","PaymentData.EVEmailRaw","PaymentData.EVName","PaymentData.EVNameRaw","PaymentData.EVPhoneNumber","PaymentData.EVPhoneNumberRaw","PaymentData.EVStreet","PaymentData.EVStreetRaw","PaymentData.EVPostalCode","PaymentData.EVPostalCodeRaw","PaymentData.BinNumber","LineItems.FulfillmentType","LineItems.Quantity","LineItems.UnitPrice","LineItems.TaxAmount","LineItems.MerchantProductSku","LineItems.ProductName","LineItems.ProductCode","LineItems.InvoiceNumber","BillTo.NameSuffix","BillTo.FirstName","BillTo.LastName","BillTo.MiddleName","BillTo.Address1","BillTo.Address2","BillTo.City","BillTo.State","BillTo.Zip","BillTo.Country","BillTo.CompanyName","BillTo.Email","BillTo.Title","BillTo.Phone","PaymentMethod.CardType","PaymentMethod.ExpirationMonth","PaymentMethod.ExpirationYear","PaymentMethod.StartMonth","PaymentMethod.StartYear","PaymentMethod.IssueNumber","PaymentMethod.AccountSuffix","PaymentMethod.AccountType","PaymentMethod.BoletoNumber","PaymentData.CardCategory","PaymentData.CardCategoryCode","PaymentMethod.WalletType","PaymentMethod.CheckNumber","PaymentMethod.MandateId","PaymentMethod.MandateType","PaymentMethod.SignatureDate","Travel.CompleteRoute","Travel.JourneyType","Travel.DepartureDateTime","Travel.PassengerFirstName","Travel.PassengerLastName","Travel.PassengerId","Travel.PassengerStatus","Travel.PassengerType","Travel.PassengerPhone","Travel.PassengerEmail","Application.Rcode","Application.Rflag","Application.Rmsg","ShipTo.Address1","ShipTo.Address2","ShipTo.City","ShipTo.State","ShipTo.Zip","ShipTo.Country","ShipTo.Phone","ShipTo.CompanyName","Application.ReasonCode","Risk.Factors","Risk.HostSeverity","Risk.Score","Risk.ConsumerPasswordProvided","Risk.LostPassword","Risk.RepeatCustomer","Risk.CookiesAccepted","Risk.ConsumerLoyalty","Risk.ConsumerPromotions","Risk.GiftWrap","Risk.ReturnsAccepted","Risk.ProductRisk","Risk.AppliedThreshold","Risk.AppliedTimeHedge","Risk.AppliedVelocityHedge","Risk.AppliedHostHedge","Risk.AppliedCategoryGift","Risk.AppliedCategoryTime","Risk.AppliedAVS","Risk.CodeValue","Risk.AppliedCV","Risk.BinAccountType","Risk.BinScheme","Risk.BinIssuer","Risk.BinCountry","Risk.IPCity","Risk.IPCountry","Risk.IPRoutingMethod","Risk.IPState","Risk.DeviceFingerPrint","Risk.CookiesEnabled","Risk.FlashEnabled","Risk.ImagesEnabled","Risk.JavascriptEnabled","Risk.ProxyIPAddress","Risk.ProxyIPAddressActivities","Risk.ProxyIPAddressAttributes","Risk.ProxyServerType","Risk.TrueIPAddress","Risk.TrueIPaddressActivities","Risk.TrueIPAddressAttributes","Risk.TrueIPAddressCountry","Risk.TrueIPAddressCity","Risk.CodeType","Risk.TimeLocal","BillTo.IPAddress","BillTo.HostName","BillTo.UserName","BillTo.CustomerID","PaymentData.Amount","PaymentData.PaymentRequestID","PaymentData.PaymentProcessor","PaymentData.TotalTaxAmount","PaymentData.EventType","PaymentData.GrandTotal","PaymentData.ECI","PaymentData.AAV_CAVV","PaymentData.XID","Profile.ProfileMode","Profile.ProfileDecision","Profile.RuleName","Profile.RuleDecision","Shipping.Method","Shipping.Carrier","Request.RequestID","Request.SubscriptionID","Request.Comments","PaymentData.TransactionRefNumber","PaymentData.eCommerceIndicator","Request.Source","Request.User","Request.TransactionDate","LineItems.Number","Request.MerchantReferenceNumber","Application.Name","Profile.Name","MerchantDefinedData.Field1","MerchantDefinedData.Field2","MerchantDefinedData.Field3","MerchantDefinedData.Field4","MerchantDefinedData.Field5","MerchantDefinedData.Field6","MerchantDefinedData.Field7","MerchantDefinedData.Field8","MerchantDefinedData.Field9","MerchantDefinedData.Field10","MerchantDefinedData.Field11","MerchantDefinedData.Field12","MerchantDefinedData.Field13","MerchantDefinedData.Field14","MerchantDefinedData.Field15","MerchantDefinedData.Field16","MerchantDefinedData.Field17","MerchantDefinedData.Field18","MerchantDefinedData.Field19","MerchantDefinedData.Field20","ShipTo.FirstName","ShipTo.LastName","Request.MerchantID","Travel.Number","PaymentData.ReconciliationID","PaymentData.TargetAmount","PaymentData.TargetCurrency","PaymentData.ExchangeRate","PaymentData.ExchangeRateDate","PaymentData.DCCIndicator","PaymentMethod.BankCode","PaymentMethod.BankAccountName","PaymentData.AuthIndicator","PaymentData.AuthReversalResult","PaymentData.AuthReversalAmount","PaymentData.CardPresent","PaymentData.POSEntryMode","PaymentData.EMVRequestFallBack","Request.PartnerOriginalTransactionID","Request.TerminalSerialNumber","PaymentData.POSCatLevel","Request.PartnerSDKVersion","PaymentData.CardVerificationMethod","PaymentData.POSEnvironment","PaymentData.TerminalIDAlternate","PaymentData.RoutingNetworkType","PaymentData.StoreAndForwardIndicator","PaymentData.PinType","PaymentData.IssuerResponseCode","PaymentData.AcquirerMerchantNumber","PaymentData.AcquirerMerchantID","PaymentData.PaymentProductCode","PaymentData.NetworkCode","PaymentData.MandateReferenceNumber","PaymentData.ProcessorTransactionID","PaymentData.ProcessorMID","PaymentData.SubMerchantCity","PaymentData.SubMerchantCountry","PaymentData.SubMerchantEmail","PaymentData.SubMerchantID","PaymentData.SubMerchantName","PaymentData.SubMerchantPhone","PaymentData.SubMerchantPostalCode","PaymentData.SubMerchantState","PaymentData.SubMerchantStreet","ChargebackAndRetrieval.ARN","ChargebackAndRetrieval.MerchantCategoryCode","ChargebackAndRetrieval.TransactionType","ChargebackAndRetrieval.CaseNumber","ChargebackAndRetrieval.ChargebackAmount","ChargebackAndRetrieval.ChargebackCurrency","ChargebackAndRetrieval.CaseIdentifier","ChargebackAndRetrieval.CaseType","ChargebackAndRetrieval.CaseTime","ChargebackAndRetrieval.ChargebackTime","ChargebackAndRetrieval.AdjustmentAmount","ChargebackAndRetrieval.AdjustmentCurrency","ChargebackAndRetrieval.FeeAmount","ChargebackAndRetrieval.FeeCurrency","ChargebackAndRetrieval.FinancialImpact","ChargebackAndRetrieval.FinancialImpactType","ChargebackAndRetrieval.PartialIndicator","ChargebackAndRetrieval.DocumentIndicator","ChargebackAndRetrieval.RespondByDate","ChargebackAndRetrieval.ChargebackReasonCode","ChargebackAndRetrieval.ChargebackReasonCodeDescription","ChargebackAndRetrieval.ResolvedToIndicator","ChargebackAndRetrieval.ResolutionTime","ChargebackAndRetrieval.ChargebackMessage","ChargebackAndRetrieval.ChargebackOriginalAmount","ChargebackAndRetrieval.ChargebackOriginalCurrency","BillTo.PersonalID","BillTo.CompanyTaxID","PaymentData.ProcessorResponseID","PaymentData.ProcessorTID","PaymentData.NetworkTransactionID","PaymentMethod.BoletoBarCodeNumber","Sender.SenderReferenceNumber","Recipient.RecipientBillingAmount","Recipient.RecipientBillingCurrency","Recipient.FirstName","Recipient.MiddleInitial","Recipient.ReferenceNumber","Recipient.LastName","Recipient.Address","Recipient.City","Recipient.State","Recipient.Country","Recipient.PostalCode","Recipient.PhoneNumber","Recipient.DOB","Sender.Address","Sender.City","Sender.State","Sender.PostalCode","Sender.Country","Sender.SourceOfFunds","Sender.FirstName","Sender.MiddleInitial","Sender.LastName","Sender.PhoneNumber","Sender.DOB","BatchFiles.BatchFileID","Device.DeviceID","Check.AccountEncoderID","Check.SecCode","Check.BankTransitNumber","BankInfo.Address","BankInfo.BranchCode","BankInfo.City","BankInfo.Country","BankInfo.Name","BankInfo.SwiftCode","FundTransfer.BankCheckDigit","FundTransfer.IbanIndicator","Token.TokenCode","Token.NetworkTokenTransType"]}}},"responses":{"201":{"description":"Created"},"304":{"description":"Not Modified"},"400":{"description":"Invalid request","schema":{"title":"reportingV3ReportsPost400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}}}}},"/reporting/v3/reports/{reportId}":{"get":{"tags":["Reports"],"summary":"Get Report based on reportId","description":"ReportId is mandatory input","operationId":"getReportByReportId","produces":["application/hal+json","application/xml"],"parameters":[{"name":"reportId","in":"path","description":"Valid Report Id","required":true,"type":"string"},{"name":"organizationId","in":"query","description":"Valid Cybersource Organization Id","pattern":"[a-zA-Z0-9-_]+","required":false,"type":"string","minLength":1,"maxLength":32}],"x-example":{"example0":{"summary":"Get Report based on reportId","value":[]}},"responses":{"200":{"description":"OK","schema":{"title":"reportingV3ReportsIdGet200Response","type":"object","properties":{"organizationId":{"type":"string","description":"CyberSource merchant id","example":"myMerchantId"},"reportId":{"type":"string","description":"Report ID Value","example":"6da01922-bb8e-a1fb-e053-7cb8d30ade29"},"reportDefinitionId":{"type":"string","description":"Report definition Id","example":"210"},"reportName":{"type":"string","description":"Report Name","example":"My Transaction Request report"},"reportMimeType":{"type":"string","example":"application/xml","description":"Report Format","enum":["application/xml","text/csv"]},"reportFrequency":{"type":"string","example":"DAILY","description":"Report Frequency Value","enum":["DAILY","WEEKLY","MONTHLY"]},"reportFields":{"type":"array","description":"List of Integer Values","items":{"type":"string"},"example":["Request.RequestID","Request.TransactionDate","Request.MerchantID"]},"reportStatus":{"type":"string","description":"Report Status Value","enum":["COMPLETED","PENDING","QUEUED","RUNNING","ERROR","NO_DATA","RERUN"]},"reportStartTime":{"type":"string","format":"date-time","example":"2017-10-01T10:10:10+05:00","description":"Report Start Time Value"},"reportEndTime":{"type":"string","format":"date-time","example":"2017-10-02T10:10:10+05:00","description":"Report End Time Value"},"timezone":{"type":"string","description":"Time Zone Value","example":"America/Chicago"},"reportFilters":{"type":"object","description":"Report Filters","additionalProperties":{"type":"array","items":{"type":"string"}}},"reportPreferences":{"description":"Report Preferences","type":"object","properties":{"signedAmounts":{"type":"boolean","description":"Indicator to determine whether negative sign infron of amount for all refunded transaction"},"fieldNameConvention":{"type":"string","description":"Specify the field naming convention to be followed in reports (applicable to only csv report formats","enum":["SOAPI","SCMP"]}}},"selectedMerchantGroupName":{"type":"string","description":"Selected Merchant Group name","example":"myGroup"}},"description":"Report Log"}},"400":{"description":"Invalid Request","schema":{"title":"reportingV3ReportsIdPost400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"No Reports Found"}}}},"/reporting/v3/report-downloads":{"get":{"tags":["ReportDownloads"],"summary":"Download a report","description":"Download a report for the given report name on the specified date","operationId":"downloadReport","produces":["application/xml","test/csv"],"parameters":[{"name":"organizationId","in":"query","description":"Valid Cybersource Organization Id","pattern":"[a-zA-Z0-9-_]+","required":false,"type":"string","minLength":1,"maxLength":32},{"name":"reportDate","in":"query","description":"Valid date on which to download the report in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd\n","required":true,"type":"string","format":"date"},{"name":"reportName","in":"query","description":"Name of the report to download","type":"string","required":true}],"x-example":{"example0":{"summary":"Download a report","value":[]}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid Request","schema":{"title":"reportingv3ReportDownloadsGet400Response","type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"No Reports Found"}}}},"/v1/file-details":{"get":{"tags":["SecureFileShare"],"summary":"Get list of files","description":"Get list of files and it's information of them available inside the report directory","operationId":"getFileDetails","produces":["application/hal+json"],"parameters":[{"name":"startDate","in":"query","description":"Valid start date in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd\n","required":true,"type":"string","format":"date"},{"name":"endDate","in":"query","description":"Valid end date in **ISO 8601 format**\nPlease refer the following link to know more about ISO 8601 format.\n- https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14\n\n **Example date format:**\n - yyyy-MM-dd\n","required":true,"type":"string","format":"date"},{"name":"organizationId","in":"query","description":"Valid Cybersource Organization Id","pattern":"[a-zA-Z0-9-_]+","required":false,"type":"string","minLength":1,"maxLength":32}],"responses":{"200":{"description":"Ok","schema":{"type":"object","title":"V1FileDetailsGet200Response","properties":{"fileDetails":{"type":"array","items":{"type":"object","properties":{"fileId":{"type":"string","description":"Unique identifier of a file","example":"AC855F9F42C90361EC78202F47CDE98D70BEAA6FB00FB56AE83EE9A9DAEE077B"},"name":{"type":"string","description":"Name of the file","example":"MyTransactionDetailreport.xml"},"createdTime":{"type":"string","format":"date-time","description":"Date and time for the file in PST","example":"2017-10-01T00:00:00+05:00"},"lastModifiedTime":{"type":"string","format":"date-time","description":"Date and time for the file in PST","example":"2017-10-01T00:00:00+05:00"},"date":{"type":"string","format":"date","description":"Date and time for the file in PST","example":"2017-10-05"},"mimeType":{"type":"string","description":"File extension","enum":["application/xml","text/csv","application/pdf","application/octet-stream"],"example":"application/xml"},"size":{"type":"integer","description":"Size of the file in bytes","example":2245397}}}},"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"/sfs/v1/file-details?startDate=2018-01-01&endDate=2018-01-02"},"method":{"type":"string","example":"GET"}}},"files":{"type":"array","items":{"type":"object","properties":{"fileId":{"type":"string","description":"Unique identifier for each file","example":"AC855F9F42C90361EC78202F47CDE98D70BEAA6FB00FB56AE83EE9A9DAEE077B"},"href":{"type":"string","example":"/sfs/v1/files/AC855F9F42C90361EC78202F47CDE98D70BEAA6FB00FB56AE83EE9A9DAEE077B"},"method":{"type":"string","example":"GET"}}}}}}}}},"400":{"description":"Invalid request","schema":{"type":"object","title":"V1FileDetailsGet400Response","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"VALIDATION_ERROR","correlationId":null,"detail":null,"fields":[{"path":"startTime","message":"Start date should not precede 18 months from current time in GMT","localizationKey":null}],"localizationKey":"cybsapi.validation.errors","message":"Field validation errors"}}},"401":{"description":"Ok","schema":{"type":"object","title":"V1FileDetailsGet401Response","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"VALIDATION_ERROR","correlationId":null,"detail":null,"fields":[{"path":"organizationId","message":"Organization doesn't has access to File details","localizationKey":null}],"localizationKey":"cybsapi.validation.errors","message":"Field validation errors"}}},"404":{"description":"Files Info not found","schema":{"type":"object","title":"V1FileDetailsGet404Response","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"RESOURCE_NOTFOUND","correlationId":null,"detail":"The requested resource is not found. Please try again later.","localizationKey":"cybsapi.resource.notfound","message":"Files Info not found for requested input values"}}},"500":{"description":"Internal Server Error","schema":{"type":"object","title":"V1FileDetailsGet500Response","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"},"examples":{"application/json":{"code":"SERVER_ERROR","correlationId":null,"detail":"Internal Server Error. Please contact the customer support.","localizationKey":"cybsapi.server.error","message":"Error encountered while processing request"}}}}}},"/v1/files/{fileId}":{"get":{"tags":["SecureFileShare"],"summary":"Download a file with file identifier","description":"Download a file for the given file identifier","operationId":"getFile","produces":["application/xml","text/csv","application/pdf"],"parameters":[{"name":"fileId","in":"path","description":"Unique identifier for each file","required":true,"type":"string"},{"name":"organizationId","in":"query","description":"Valid Cybersource Organization Id","pattern":"[a-zA-Z0-9-_]+","required":false,"type":"string","minLength":1,"maxLength":32}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid Request","schema":{"type":"object","title":"V1FilesGet400Response","required":["code","message"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"localizationKey":{"type":"string","description":"Localization Key Name"},"correlationId":{"type":"string","description":"Correlation Id"},"detail":{"type":"string","description":"Error Detail"},"fields":{"type":"array","description":"Error fields List","items":{"type":"object","properties":{"path":{"type":"string","description":"Path of the failed property"},"message":{"type":"string","description":"Error description about validation failed field"},"localizationKey":{"type":"string","description":"Localized Key Name"}},"description":"Provide validation failed input field details"}}},"description":"Error Bean"}},"404":{"description":"No Reports Found"}}}},"/tms/v1/instrumentidentifiers":{"post":{"summary":"Create an Instrument Identifier","parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"Body","in":"body","description":"Please specify either a Card or Bank Account.","required":true,"schema":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}}}],"tags":["InstrumentIdentifiers"],"x-example":{"example0":{"summary":"Create an Instrument Identifier","value":{"card":{"number":"1234567890987654"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":"123456789012345"}}}}}}},"responses":{"200":{"description":"An existing Instrument Identifier holding the same supplied data has been returned.","headers":{"Location":{"description":"Link to the Instrument Identifier.","type":"string"},"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"object","title":"tmsV1InstrumentidentifiersPost200Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}},"examples":{"application/json":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}},"paymentInstruments":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789/paymentinstruments"},"id":"1234567890123456789","object":"instrumentIdentifier","state":"ACTIVE","card":{"number":"444444XXXXXX4444"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":"123456789012345"}}}},"metadata":{"creator":"user"}}}},"201":{"description":"A new Instrument Identifier has been created.","headers":{"Location":{"description":"Link to the Instrument identifier.","type":"string"},"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"object","title":"tmsV1InstrumentidentifiersPost201Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}},"examples":{"application/json":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"},"paymentInstruments":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789/paymentinstruments"}},"id":"1234567890123456789","object":"instrumentIdentifier","state":"ACTIVE","card":{"number":"444444XXXXXX4444"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":"123456789012345"}}}},"metadata":{"creator":"user"}}}},"400":{"description":"Bad Request: e.g. A required header value could be missing.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPost400Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"Missing Headers":{"errors":[{"type":"missingHeaders","message":"Missing header values"}]}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPost403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPost424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPost500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}}},"/tms/v1/instrumentidentifiers/{tokenId}":{"get":{"summary":"Retrieve an Instrument Identifier","parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"tokenId","in":"path","description":"The TokenId of an Instrument Identifier.","required":true,"type":"string","minimum":16,"maximum":32}],"tags":["InstrumentIdentifier"],"responses":{"200":{"description":"An existing Instrument Identifier associated with the supplied tokenId has been returned.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"object","title":"tmsV1InstrumentidentifiersGet200Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}},"x-examples":{"application/json":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"},"paymentInstruments":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789/paymentinstruments"}},"id":"1234567890123456789","object":"instrumentIdentifier","state":"ACTIVE","card":{"number":"444444XXXXXX4444"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":"123456789012345"}}}},"metadata":{"creator":"user"}}}},"400":{"description":"Bad Request: e.g. A required header value could be missing.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersGet400Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"Missing Headers":{"errors":[{"type":"missingHeaders","message":"Missing header values"}]}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersGet403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"404":{"description":"Token Not Found: e.g. The tokenid may not exist or was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersGet404Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Token not found"}]}}},"410":{"description":"Token Not Available: e.g. The token has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersGet410Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notAvailable","message":"Token not available"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersGet424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersGet500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}},"patch":{"summary":"Update a Instrument Identifier","parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"tokenId","in":"path","description":"The TokenId of an Instrument Identifier.","required":true,"type":"string","minimum":16,"maximum":32},{"name":"Body","in":"body","description":"Please specify the previous transaction Id to update.","required":true,"schema":{"type":"object","properties":{"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}}}}}],"tags":["InstrumentIdentifier"],"x-example":{"example0":{"summary":"Create an Instrument Identifier","value":{"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":"123456789012345"}}}}}}},"responses":{"200":{"description":"The updated Instrument Identifier has been returned.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"object","title":"tmsV1InstrumentidentifiersPatch200Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}},"examples":{"application/json":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/58FEBAEFD2EEFCE1E0539399D30A7500"}},"id":"58FEBAEFD2EEFCE1E0539399D30A7500","object":"instrumentIdentifier","state":"ACTIVE","card":{"number":"424242XXXXXX4242"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":123456789012345}}}},"metadata":{"creator":"user"}}}},"400":{"description":"Bad Request: e.g. A required header value could be missing.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPatch400Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"Missing Headers":{"errors":[{"type":"missingHeaders","message":"Missing header values"}]},"Invalid Parameters":{"errors":[{"type":"invalidParameters","message":"Invalid parameter values","details":[{"name":"id"}]}]},"Unknown Field":{"errors":[{"type":"unknownField","message":"Unknown body values","details":[{"name":"id"}]}]},"Unsupported Fields":{"errors":[{"type":"unsupportedFields","message":"Unsupported body values for this action","details":[{"name":"bankAccount"},{"name":"card"}]}]}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPatch403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"404":{"description":"Token Not Found: e.g. The tokenid may not exist or was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPatch404Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Token not found"}]}}},"410":{"description":"Token Not Available: e.g. The token has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPatch410Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notAvailable","message":"Token not available"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPatch424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPatch500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}},"delete":{"summary":"Delete an Instrument Identifier","tags":["InstrumentIdentifier"],"parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"tokenId","in":"path","description":"The TokenId of an Instrument Identifier.","required":true,"type":"string","minimum":16,"maximum":32}],"responses":{"204":{"description":"An existing Instrument Identifier associated with the supplied tokenId has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersDelete403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"404":{"description":"Token Not Found: e.g. The tokenid may not exist or was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersDelete404Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Token not found"}]}}},"409":{"description":"Conflict: e.g. The token is linked to a Payment Instrument.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersDelete409Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"paymentInstruments":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789/paymentinstruments"}}}}}},"items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"_links":{"paymentInstruments":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/7010000000001621111/paymentinstruments"}},"errors":[{"type":"instrumentIdentifierDeletionError","message":"Action cannot be performed as the InstrumentIdentifier is associated with one or more PaymentInstruments."}]}}},"410":{"description":"Token Not Available: e.g. The token has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersDelete410Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notAvailable","message":"Token not available"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersDelete424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersDelete500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}}},"/tms/v1/instrumentidentifiers/{tokenId}/paymentinstruments":{"get":{"summary":"Retrieve all Payment Instruments associated with an Instrument Identifier","parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"tokenId","in":"path","description":"The TokenId of an Instrument Identifier.","required":true,"type":"string","minimum":16,"maximum":32},{"name":"offset","in":"query","description":"Starting Payment Instrument record in zero-based dataset that should be returned as the first object in the array. Default is 0.","required":false,"type":"string","minimum":0},{"name":"limit","in":"query","description":"The maximum number of Payment Instruments that can be returned in the array starting from the offset record in zero-based dataset. Default is 20, maximum is 100.","required":false,"type":"string","default":"20","minimum":1,"maximum":100}],"tags":["PaymentInstruments"],"responses":{"200":{"description":"Returns an array of Payment Instruments associated with the supplied Instrument Identifier.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"},"x-Total-Count":{"description":"The total number of Payment Instruments associated with the Instrument Identifier in the zero-based dataset.","type":"string"}},"schema":{"type":"object","title":"tmsV1InstrumentidentifiersPaymentinstrumentsGet200Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"A link to the current requested collection.","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=20&limit=5\""}}},"first":{"type":"object","properties":{"href":{"type":"string","description":"A link to the collection starting at offset zero for the supplied limit.","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=0&limit=5"}}},"prev":{"type":"object","description":"A link to the previous collection starting at the supplied offset minus the supplied limit.","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=15&limit=5"}}},"next":{"type":"object","properties":{"href":{"description":"A link to the next collection starting at the supplied offset plus the supplied limit.","type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=25&limit=5"}}},"last":{"type":"object","properties":{"href":{"description":"A link to the last collection containing the remaining objects.","type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=35&limit=5"}}}}},"object":{"type":"string","readOnly":true,"example":"collection","description":"Shows the response is a collection of objects.","enum":["collection"]},"offset":{"type":"string","readOnly":true,"example":"20","description":"The offset parameter supplied in the request."},"limit":{"type":"string","readOnly":true,"example":"1","description":"The limit parameter supplied in the request."},"count":{"type":"string","readOnly":true,"example":"1","description":"The number of Payment Instruments returned in the array."},"total":{"type":"string","readOnly":true,"example":"39","description":"The total number of Payment Instruments associated with the Instrument Identifier in the zero-based dataset."},"_embedded":{"type":"object","description":"Array of Payment Instruments returned for the supplied Instrument Identifier.","items":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["paymentInstrument"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"bankAccount":{"type":"object","properties":{"type":{"type":"string","example":"savings","description":"Type of Bank Account."}}},"card":{"type":"object","properties":{"expirationMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card expiration month."},"expirationYear":{"type":"string","example":"2022","minimum":1900,"maximum":2099,"description":"Credit card expiration year."},"type":{"type":"string","example":"visa","description":"Credit card brand.","enum":["visa","mastercard","american express","discover","diners club","carte blanche","jcb","optima","twinpay credit","twinpay debit","walmart","enroute","lowes consumer","home depot consumer","mbna","dicks sportswear","casual corner","sears","jal","disney","maestro uk domestic","sams club consumer","sams club business","nicos","bill me later","bebe","restoration hardware","delta online","solo","visa electron","dankort","laser","carte bleue","carta si","pinless debit","encoded account","uatp","household","maestro international","ge money uk","korean cards","style","jcrew","payease china processing ewallet","payease china processing bank transfer","meijer private label","hipercard","aura","redecard","orico","elo","capital one private label","synchrony private label","china union pay"]},"issueNumber":{"type":"string","example":"01","minimum":0,"maximum":99,"description":"Credit card issue number."},"startMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card start month."},"startYear":{"type":"string","example":"12","minimum":1900,"maximum":2099,"description":"Credit card start year."},"useAs":{"type":"string","example":"pinless debit","description":"Card Use As Field. Supported value of \"pinless debit\" only. Only for use with Pinless Debit tokens."}}},"buyerInformation":{"type":"object","properties":{"companyTaxID":{"type":"string","example":"1234567890123456800","maximum":9,"description":"Company Tax ID."},"currency":{"type":"string","example":"USD","minimum":3,"maximum":3,"description":"Currency. Accepts input in the ISO 4217 standard, stores as ISO 4217 Alpha"},"dateOBirth":{"type":"string","example":"1960-12-30","description":"Date of birth YYYY-MM-DD."},"personalIdentification":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"1234567890","description":"Identification Number."},"type":{"type":"string","example":"driver license","description":"Type of personal identification."},"issuedBy":{"type":"object","properties":{"administrativeArea":{"type":"string","example":"CA","description":"State or province where the identification was issued."}}}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","example":"John","maximum":60,"description":"Bill to First Name."},"lastName":{"type":"string","example":"Smith","maximum":60,"description":"Bill to Last Name."},"company":{"type":"string","example":"CyberSource","maximum":60,"description":"Bill to Company."},"address1":{"type":"string","example":"12 Main Street","maximum":60,"description":"Bill to Address Line 1."},"address2":{"type":"string","example":"20 My Street","maximum":60,"description":"Bill to Address Line 2."},"locality":{"type":"string","example":"Foster City","maximum":50,"description":"Bill to City."},"administrativeArea":{"type":"string","example":"CA","maximum":20,"description":"Bill to State."},"postalCode":{"type":"string","example":"90200","maximum":10,"description":"Bill to Postal Code."},"country":{"type":"string","example":"US","minimum":2,"maximum":3,"description":"Bill to Country. Accepts input in the ISO 3166-1 standard, stores as ISO 3166-1-Alpha-2"},"email":{"type":"string","example":"john.smith@example.com","maximum":320,"description":"Valid Bill to Email."},"phoneNumber":{"type":"string","example":"555123456","minimum":6,"maximum":32,"description":"Bill to Phone Number."}}},"processingInformation":{"type":"object","properties":{"billPaymentProgramEnabled":{"type":"boolean","example":true,"description":"Bill Payment Program Enabled."},"bankTransferOptions":{"type":"object","properties":{"SECCode":{"type":"string","example":"WEB","description":"Authorization method used for the transaction.(acceptable values are CCD, PPD, TEL, WEB)."}}}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"alternateName":{"type":"string","example":"Branch Name","description":"Alternate information for your business. This API field overrides the company entry description value in your CyberSource account."}}}}},"metaData":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}},"instrumentIdentifier":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"id":{"type":"string","example":"1234567890123456789","minimum":16,"maximum":32,"description":"The id of the existing instrument identifier to be linked to the newly created payment instrument."},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}}}}}}},"examples":{"application/json":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=20&limit=1"},"first":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=0&limit=1"},"prev":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=19&limit=1"},"next":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=21&limit=1\""},"last":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1/paymentinstruments?offset=38&limit=1"}},"object":"collection","offset":20,"limit":1,"count":1,"total":39,"_embedded":{"paymentInstruments":[{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/paymentinstruments/6036673B73B12F19E0539399D30A2566"}},"id":"6036673B73B12F19E0539399D30A2566","object":"paymentInstrument","state":"ACTIVE","card":{"expirationMonth":"09","expirationYear":"2027","type":"visa","issueNumber":"01","startMonth":"01","startYear":"2017"},"buyerInformation":{"companyTaxId":"12345","currency":"USD"},"billTo":{"firstName":"John","lastName":"Smith","company":"CyberSource","address1":"1 My Apartment","address2":"Main Street","locality":"San Francisco","administrativeArea":"CA","postalCode":"90211","country":"US","email":"john.smith@test.com","phoneNumber":"+44 2890447777"},"processingInformation":{"billPaymentProgramEnabled":true},"metadata":{"creator":"user"},"_embedded":{"instrumentIdentifier":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/5B32CE6167B09343E05333B9D30A53E1"}},"id":"5B32CE6167B09343E05333B9D30A53E1","object":"instrumentIdentifier","state":"ACTIVE","card":{"number":"424242XXXXXX1237"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":"123456789012345"}}}},"metadata":{"creator":"user"}}}}]}}}},"400":{"description":"Bad Request: e.g. A required header value could be missing.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPaymentinstrumentsGet400Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"Missing Headers":{"errors":[{"type":"missingHeaders","message":"Missing header values"}]}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPaymentinstrumentsGet403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"404":{"description":"Token Not Found: e.g. The tokenid may not exist or was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPaymentinstrumentsGet404Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Token not found"}]}}},"410":{"description":"Token Not Available: e.g. The token has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPaymentinstrumentsGet410Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notAvailable","message":"Token not available"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPaymentinstrumentsGet424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1InstrumentidentifiersPaymentinstrumentsGet500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}}},"/tms/v1/paymentinstruments":{"post":{"summary":"Create a Payment Instrument","parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"Body","in":"body","description":"Please specify the customers payment details for card or bank account.","required":true,"schema":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["paymentInstrument"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"bankAccount":{"type":"object","properties":{"type":{"type":"string","example":"savings","description":"Type of Bank Account."}}},"card":{"type":"object","properties":{"expirationMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card expiration month."},"expirationYear":{"type":"string","example":"2022","minimum":1900,"maximum":2099,"description":"Credit card expiration year."},"type":{"type":"string","example":"visa","description":"Credit card brand.","enum":["visa","mastercard","american express","discover","diners club","carte blanche","jcb","optima","twinpay credit","twinpay debit","walmart","enroute","lowes consumer","home depot consumer","mbna","dicks sportswear","casual corner","sears","jal","disney","maestro uk domestic","sams club consumer","sams club business","nicos","bill me later","bebe","restoration hardware","delta online","solo","visa electron","dankort","laser","carte bleue","carta si","pinless debit","encoded account","uatp","household","maestro international","ge money uk","korean cards","style","jcrew","payease china processing ewallet","payease china processing bank transfer","meijer private label","hipercard","aura","redecard","orico","elo","capital one private label","synchrony private label","china union pay"]},"issueNumber":{"type":"string","example":"01","minimum":0,"maximum":99,"description":"Credit card issue number."},"startMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card start month."},"startYear":{"type":"string","example":"12","minimum":1900,"maximum":2099,"description":"Credit card start year."},"useAs":{"type":"string","example":"pinless debit","description":"Card Use As Field. Supported value of \"pinless debit\" only. Only for use with Pinless Debit tokens."}}},"buyerInformation":{"type":"object","properties":{"companyTaxID":{"type":"string","example":"1234567890123456800","maximum":9,"description":"Company Tax ID."},"currency":{"type":"string","example":"USD","minimum":3,"maximum":3,"description":"Currency. Accepts input in the ISO 4217 standard, stores as ISO 4217 Alpha"},"dateOBirth":{"type":"string","example":"1960-12-30","description":"Date of birth YYYY-MM-DD."},"personalIdentification":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"1234567890","description":"Identification Number."},"type":{"type":"string","example":"driver license","description":"Type of personal identification."},"issuedBy":{"type":"object","properties":{"administrativeArea":{"type":"string","example":"CA","description":"State or province where the identification was issued."}}}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","example":"John","maximum":60,"description":"Bill to First Name."},"lastName":{"type":"string","example":"Smith","maximum":60,"description":"Bill to Last Name."},"company":{"type":"string","example":"CyberSource","maximum":60,"description":"Bill to Company."},"address1":{"type":"string","example":"12 Main Street","maximum":60,"description":"Bill to Address Line 1."},"address2":{"type":"string","example":"20 My Street","maximum":60,"description":"Bill to Address Line 2."},"locality":{"type":"string","example":"Foster City","maximum":50,"description":"Bill to City."},"administrativeArea":{"type":"string","example":"CA","maximum":20,"description":"Bill to State."},"postalCode":{"type":"string","example":"90200","maximum":10,"description":"Bill to Postal Code."},"country":{"type":"string","example":"US","minimum":2,"maximum":3,"description":"Bill to Country. Accepts input in the ISO 3166-1 standard, stores as ISO 3166-1-Alpha-2"},"email":{"type":"string","example":"john.smith@example.com","maximum":320,"description":"Valid Bill to Email."},"phoneNumber":{"type":"string","example":"555123456","minimum":6,"maximum":32,"description":"Bill to Phone Number."}}},"processingInformation":{"type":"object","properties":{"billPaymentProgramEnabled":{"type":"boolean","example":true,"description":"Bill Payment Program Enabled."},"bankTransferOptions":{"type":"object","properties":{"SECCode":{"type":"string","example":"WEB","description":"Authorization method used for the transaction.(acceptable values are CCD, PPD, TEL, WEB)."}}}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"alternateName":{"type":"string","example":"Branch Name","description":"Alternate information for your business. This API field overrides the company entry description value in your CyberSource account."}}}}},"metaData":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}},"instrumentIdentifier":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"id":{"type":"string","example":"1234567890123456789","minimum":16,"maximum":32,"description":"The id of the existing instrument identifier to be linked to the newly created payment instrument."},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}}}}}],"tags":["PaymentInstruments"],"x-example":{"example0":{"summary":"Create an payment Identifier","value":{"card":{"expirationMonth":"09","expirationYear":"2022","type":"visa"},"billTo":{"firstName":"John","lastName":"Smith","company":"CyberSource","address1":"12 Main Street","address2":"20 My Street","locality":"Foster City","administrativeArea":"CA","postalCode":"90200","country":"US","email":"john.smith@example.com","phoneNumber":"555123456"},"instrumentIdentifier":{"card":{"number":"4111111111111111"}}}}},"responses":{"201":{"description":"A new Payment Instrument has been created.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"object","title":"tmsV1PaymentinstrumentsPost201Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["paymentInstrument"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"bankAccount":{"type":"object","properties":{"type":{"type":"string","example":"savings","description":"Type of Bank Account."}}},"card":{"type":"object","properties":{"expirationMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card expiration month."},"expirationYear":{"type":"string","example":"2022","minimum":1900,"maximum":2099,"description":"Credit card expiration year."},"type":{"type":"string","example":"visa","description":"Credit card brand.","enum":["visa","mastercard","american express","discover","diners club","carte blanche","jcb","optima","twinpay credit","twinpay debit","walmart","enroute","lowes consumer","home depot consumer","mbna","dicks sportswear","casual corner","sears","jal","disney","maestro uk domestic","sams club consumer","sams club business","nicos","bill me later","bebe","restoration hardware","delta online","solo","visa electron","dankort","laser","carte bleue","carta si","pinless debit","encoded account","uatp","household","maestro international","ge money uk","korean cards","style","jcrew","payease china processing ewallet","payease china processing bank transfer","meijer private label","hipercard","aura","redecard","orico","elo","capital one private label","synchrony private label","china union pay"]},"issueNumber":{"type":"string","example":"01","minimum":0,"maximum":99,"description":"Credit card issue number."},"startMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card start month."},"startYear":{"type":"string","example":"12","minimum":1900,"maximum":2099,"description":"Credit card start year."},"useAs":{"type":"string","example":"pinless debit","description":"Card Use As Field. Supported value of \"pinless debit\" only. Only for use with Pinless Debit tokens."}}},"buyerInformation":{"type":"object","properties":{"companyTaxID":{"type":"string","example":"1234567890123456800","maximum":9,"description":"Company Tax ID."},"currency":{"type":"string","example":"USD","minimum":3,"maximum":3,"description":"Currency. Accepts input in the ISO 4217 standard, stores as ISO 4217 Alpha"},"dateOBirth":{"type":"string","example":"1960-12-30","description":"Date of birth YYYY-MM-DD."},"personalIdentification":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"1234567890","description":"Identification Number."},"type":{"type":"string","example":"driver license","description":"Type of personal identification."},"issuedBy":{"type":"object","properties":{"administrativeArea":{"type":"string","example":"CA","description":"State or province where the identification was issued."}}}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","example":"John","maximum":60,"description":"Bill to First Name."},"lastName":{"type":"string","example":"Smith","maximum":60,"description":"Bill to Last Name."},"company":{"type":"string","example":"CyberSource","maximum":60,"description":"Bill to Company."},"address1":{"type":"string","example":"12 Main Street","maximum":60,"description":"Bill to Address Line 1."},"address2":{"type":"string","example":"20 My Street","maximum":60,"description":"Bill to Address Line 2."},"locality":{"type":"string","example":"Foster City","maximum":50,"description":"Bill to City."},"administrativeArea":{"type":"string","example":"CA","maximum":20,"description":"Bill to State."},"postalCode":{"type":"string","example":"90200","maximum":10,"description":"Bill to Postal Code."},"country":{"type":"string","example":"US","minimum":2,"maximum":3,"description":"Bill to Country. Accepts input in the ISO 3166-1 standard, stores as ISO 3166-1-Alpha-2"},"email":{"type":"string","example":"john.smith@example.com","maximum":320,"description":"Valid Bill to Email."},"phoneNumber":{"type":"string","example":"555123456","minimum":6,"maximum":32,"description":"Bill to Phone Number."}}},"processingInformation":{"type":"object","properties":{"billPaymentProgramEnabled":{"type":"boolean","example":true,"description":"Bill Payment Program Enabled."},"bankTransferOptions":{"type":"object","properties":{"SECCode":{"type":"string","example":"WEB","description":"Authorization method used for the transaction.(acceptable values are CCD, PPD, TEL, WEB)."}}}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"alternateName":{"type":"string","example":"Branch Name","description":"Alternate information for your business. This API field overrides the company entry description value in your CyberSource account."}}}}},"metaData":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}},"instrumentIdentifier":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"id":{"type":"string","example":"1234567890123456789","minimum":16,"maximum":32,"description":"The id of the existing instrument identifier to be linked to the newly created payment instrument."},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}}}},"examples":{"application/json":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/paymentinstruments/5910683634E6B035E0539399D30A4B46"}},"id":"5910683634E6B035E0539399D30A4B46","object":"paymentInstrument","state":"ACTIVE","card":{"expirationMonth":11,"expirationYear":2020,"type":"visa","issueNumber":1,"startMonth":12,"startYear":2017},"buyerInformation":{"companyTaxID":12345,"currency":"USD"},"billTo":{"firstName":"John","lastName":"Smith","company":"Cybersource","address1":"1 My Apartment","address2":"20 My Street","locality":"San Francisco","administrativeArea":"CA","postalCode":90210,"country":"US","email":"ohn.smith@test.com","phoneNumber":"+44 289044795"},"processingInformation":{"billPaymentProgramEnabled":true},"metadata":{"creator":"user"},"_embedded":{"instrumentIdentifier":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/58FEBAEFD2EEFCE1E0539399D30A7500"}},"id":"58FEBAEFD2EEFCE1E0539399D30A7500","object":"instrumentIdentifier","state":"ACTIVE","card":{"number":"424242XXXXXX4242"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":123456789012345}}}},"metadata":{"creator":"user"}}}}}},"400":{"description":"Bad Request: e.g. A required header value could be missing.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPost400Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"Missing Headers":{"errors":[{"type":"missingHeaders","message":"Missing header values"}]},"Payment Instrument cannot be linked to instrument identifier because it does not exist":{"errors":[{"type":"instrumentIdentifierNotFound","message":"Action cannot be performed as the InstrumentIdentifier is not found"}]},"Payment Instrument cannot be linked to instrument identifier because it has been deleted":{"errors":[{"type":"instrumentIdentifierGone","message":"Action cannot be performed as the InstrumentIdentifier has gone"}]},"Payment Instrument cannot be linked to instrument identifier due to a token type mismatch":{"errors":[{"type":"invalidCombination","message":"The combination is invalid","details":[{"name":"bankAccount"},{"name":"card","location":"instrumentIdentifier"}]}]},"Payment Instrument cannot be created due to invalid combination of Instrument Identifier fields":{"errors":[{"type":"invalidCombination","message":"The combination is invalid","details":[{"name":"id","location":"instrumentIdentifier"},{"name":"card","location":"instrumentIdentifier"}]}]}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPost403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPost424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPost500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}}},"/tms/v1/paymentinstruments/{tokenId}":{"patch":{"summary":"Update a Payment Instrument","parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"tokenId","in":"path","description":"The TokenId of a Payment Instrument.","required":true,"type":"string","minimum":16,"maximum":32},{"name":"Body","in":"body","description":"Please specify the customers payment details.","required":true,"schema":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["paymentInstrument"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"bankAccount":{"type":"object","properties":{"type":{"type":"string","example":"savings","description":"Type of Bank Account."}}},"card":{"type":"object","properties":{"expirationMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card expiration month."},"expirationYear":{"type":"string","example":"2022","minimum":1900,"maximum":2099,"description":"Credit card expiration year."},"type":{"type":"string","example":"visa","description":"Credit card brand.","enum":["visa","mastercard","american express","discover","diners club","carte blanche","jcb","optima","twinpay credit","twinpay debit","walmart","enroute","lowes consumer","home depot consumer","mbna","dicks sportswear","casual corner","sears","jal","disney","maestro uk domestic","sams club consumer","sams club business","nicos","bill me later","bebe","restoration hardware","delta online","solo","visa electron","dankort","laser","carte bleue","carta si","pinless debit","encoded account","uatp","household","maestro international","ge money uk","korean cards","style","jcrew","payease china processing ewallet","payease china processing bank transfer","meijer private label","hipercard","aura","redecard","orico","elo","capital one private label","synchrony private label","china union pay"]},"issueNumber":{"type":"string","example":"01","minimum":0,"maximum":99,"description":"Credit card issue number."},"startMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card start month."},"startYear":{"type":"string","example":"12","minimum":1900,"maximum":2099,"description":"Credit card start year."},"useAs":{"type":"string","example":"pinless debit","description":"Card Use As Field. Supported value of \"pinless debit\" only. Only for use with Pinless Debit tokens."}}},"buyerInformation":{"type":"object","properties":{"companyTaxID":{"type":"string","example":"1234567890123456800","maximum":9,"description":"Company Tax ID."},"currency":{"type":"string","example":"USD","minimum":3,"maximum":3,"description":"Currency. Accepts input in the ISO 4217 standard, stores as ISO 4217 Alpha"},"dateOBirth":{"type":"string","example":"1960-12-30","description":"Date of birth YYYY-MM-DD."},"personalIdentification":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"1234567890","description":"Identification Number."},"type":{"type":"string","example":"driver license","description":"Type of personal identification."},"issuedBy":{"type":"object","properties":{"administrativeArea":{"type":"string","example":"CA","description":"State or province where the identification was issued."}}}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","example":"John","maximum":60,"description":"Bill to First Name."},"lastName":{"type":"string","example":"Smith","maximum":60,"description":"Bill to Last Name."},"company":{"type":"string","example":"CyberSource","maximum":60,"description":"Bill to Company."},"address1":{"type":"string","example":"12 Main Street","maximum":60,"description":"Bill to Address Line 1."},"address2":{"type":"string","example":"20 My Street","maximum":60,"description":"Bill to Address Line 2."},"locality":{"type":"string","example":"Foster City","maximum":50,"description":"Bill to City."},"administrativeArea":{"type":"string","example":"CA","maximum":20,"description":"Bill to State."},"postalCode":{"type":"string","example":"90200","maximum":10,"description":"Bill to Postal Code."},"country":{"type":"string","example":"US","minimum":2,"maximum":3,"description":"Bill to Country. Accepts input in the ISO 3166-1 standard, stores as ISO 3166-1-Alpha-2"},"email":{"type":"string","example":"john.smith@example.com","maximum":320,"description":"Valid Bill to Email."},"phoneNumber":{"type":"string","example":"555123456","minimum":6,"maximum":32,"description":"Bill to Phone Number."}}},"processingInformation":{"type":"object","properties":{"billPaymentProgramEnabled":{"type":"boolean","example":true,"description":"Bill Payment Program Enabled."},"bankTransferOptions":{"type":"object","properties":{"SECCode":{"type":"string","example":"WEB","description":"Authorization method used for the transaction.(acceptable values are CCD, PPD, TEL, WEB)."}}}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"alternateName":{"type":"string","example":"Branch Name","description":"Alternate information for your business. This API field overrides the company entry description value in your CyberSource account."}}}}},"metaData":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}},"instrumentIdentifier":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"id":{"type":"string","example":"1234567890123456789","minimum":16,"maximum":32,"description":"The id of the existing instrument identifier to be linked to the newly created payment instrument."},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}}}}}],"tags":["PaymentInstruments"],"x-example":{"example0":{"summary":"Update Payment Instrument","value":{"card":{"expirationMonth":"09","expirationYear":"2022","type":"visa"},"billTo":{"firstName":"John","lastName":"Smith","company":"CyberSource","address1":"12 Main Street","address2":"20 My Street","locality":"Foster City","administrativeArea":"CA","postalCode":"90200","country":"US","email":"john.smith@example.com","phoneNumber":"555123456"},"instrumentIdentifier":{"card":{"number":"4111111111111111"}}}}},"responses":{"200":{"description":"The updated Payment Instrument has been returned.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"object","title":"tmsV1PaymentinstrumentsPatch200Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["paymentInstrument"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"bankAccount":{"type":"object","properties":{"type":{"type":"string","example":"savings","description":"Type of Bank Account."}}},"card":{"type":"object","properties":{"expirationMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card expiration month."},"expirationYear":{"type":"string","example":"2022","minimum":1900,"maximum":2099,"description":"Credit card expiration year."},"type":{"type":"string","example":"visa","description":"Credit card brand.","enum":["visa","mastercard","american express","discover","diners club","carte blanche","jcb","optima","twinpay credit","twinpay debit","walmart","enroute","lowes consumer","home depot consumer","mbna","dicks sportswear","casual corner","sears","jal","disney","maestro uk domestic","sams club consumer","sams club business","nicos","bill me later","bebe","restoration hardware","delta online","solo","visa electron","dankort","laser","carte bleue","carta si","pinless debit","encoded account","uatp","household","maestro international","ge money uk","korean cards","style","jcrew","payease china processing ewallet","payease china processing bank transfer","meijer private label","hipercard","aura","redecard","orico","elo","capital one private label","synchrony private label","china union pay"]},"issueNumber":{"type":"string","example":"01","minimum":0,"maximum":99,"description":"Credit card issue number."},"startMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card start month."},"startYear":{"type":"string","example":"12","minimum":1900,"maximum":2099,"description":"Credit card start year."},"useAs":{"type":"string","example":"pinless debit","description":"Card Use As Field. Supported value of \"pinless debit\" only. Only for use with Pinless Debit tokens."}}},"buyerInformation":{"type":"object","properties":{"companyTaxID":{"type":"string","example":"1234567890123456800","maximum":9,"description":"Company Tax ID."},"currency":{"type":"string","example":"USD","minimum":3,"maximum":3,"description":"Currency. Accepts input in the ISO 4217 standard, stores as ISO 4217 Alpha"},"dateOBirth":{"type":"string","example":"1960-12-30","description":"Date of birth YYYY-MM-DD."},"personalIdentification":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"1234567890","description":"Identification Number."},"type":{"type":"string","example":"driver license","description":"Type of personal identification."},"issuedBy":{"type":"object","properties":{"administrativeArea":{"type":"string","example":"CA","description":"State or province where the identification was issued."}}}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","example":"John","maximum":60,"description":"Bill to First Name."},"lastName":{"type":"string","example":"Smith","maximum":60,"description":"Bill to Last Name."},"company":{"type":"string","example":"CyberSource","maximum":60,"description":"Bill to Company."},"address1":{"type":"string","example":"12 Main Street","maximum":60,"description":"Bill to Address Line 1."},"address2":{"type":"string","example":"20 My Street","maximum":60,"description":"Bill to Address Line 2."},"locality":{"type":"string","example":"Foster City","maximum":50,"description":"Bill to City."},"administrativeArea":{"type":"string","example":"CA","maximum":20,"description":"Bill to State."},"postalCode":{"type":"string","example":"90200","maximum":10,"description":"Bill to Postal Code."},"country":{"type":"string","example":"US","minimum":2,"maximum":3,"description":"Bill to Country. Accepts input in the ISO 3166-1 standard, stores as ISO 3166-1-Alpha-2"},"email":{"type":"string","example":"john.smith@example.com","maximum":320,"description":"Valid Bill to Email."},"phoneNumber":{"type":"string","example":"555123456","minimum":6,"maximum":32,"description":"Bill to Phone Number."}}},"processingInformation":{"type":"object","properties":{"billPaymentProgramEnabled":{"type":"boolean","example":true,"description":"Bill Payment Program Enabled."},"bankTransferOptions":{"type":"object","properties":{"SECCode":{"type":"string","example":"WEB","description":"Authorization method used for the transaction.(acceptable values are CCD, PPD, TEL, WEB)."}}}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"alternateName":{"type":"string","example":"Branch Name","description":"Alternate information for your business. This API field overrides the company entry description value in your CyberSource account."}}}}},"metaData":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}},"instrumentIdentifier":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"id":{"type":"string","example":"1234567890123456789","minimum":16,"maximum":32,"description":"The id of the existing instrument identifier to be linked to the newly created payment instrument."},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}}}},"examples":{"application/json":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/paymentinstruments/5910683634E6B035E0539399D30A4B46"}},"id":"5910683634E6B035E0539399D30A4B46","object":"paymentInstrument","state":"ACTIVE","card":{"expirationMonth":11,"expirationYear":2020,"type":"visa","issueNumber":1,"startMonth":12,"startYear":2017},"buyerInformation":{"companyTaxID":12345,"currency":"USD"},"billTo":{"firstName":"John","lastName":"Smith","company":"Cybersource","address1":"1 My Apartment","address2":"20 My Street","locality":"San Francisco","administrativeArea":"CA","postalCode":90210,"country":"US","email":"ohn.smith@test.com","phoneNumber":"+44 289044795"},"processingInformation":{"billPaymentProgramEnabled":true},"metadata":{"creator":"user"},"_embedded":{"instrumentIdentifier":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/58FEBAEFD2EEFCE1E0539399D30A7500"}},"id":"58FEBAEFD2EEFCE1E0539399D30A7500","object":"instrumentIdentifier","state":"ACTIVE","card":{"number":"424242XXXXXX4242"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":123456789012345}}}},"metadata":{"creator":"user"}}}}}},"400":{"description":"Bad Request: e.g. A required header value could be missing.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPatch400Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"Missing Headers":{"errors":[{"type":"missingHeaders","message":"Missing header values"}]},"Payment Instrument cannot be linked to instrument identifier because it does not exist":{"errors":[{"type":"instrumentIdentifierNotFound","message":"Action cannot be performed as the InstrumentIdentifier is not found"}]},"Payment Instrument cannot be linked to instrument identifier because it has been deleted":{"errors":[{"type":"instrumentIdentifierGone","message":"Action cannot be performed as the InstrumentIdentifier has gone"}]},"Payment Instrument cannot be linked to instrument identifier due to a token type mismatch":{"errors":[{"type":"invalidCombination","message":"The combination is invalid","details":[{"name":"bankAccount"},{"name":"card","location":"instrumentIdentifier"}]}]},"Payment Instrument cannot be created due to invalid combination of Instrument Identifier fields":{"errors":[{"type":"invalidCombination","message":"The combination is invalid","details":[{"name":"id","location":"instrumentIdentifier"},{"name":"card","location":"instrumentIdentifier"}]}]}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPatch403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"404":{"description":"Token Not Found: e.g. The tokenid may not exist or was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPatch404Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Token not found"}]}}},"410":{"description":"Token Not Available: e.g. The token has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPatch410Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notAvailable","message":"Token not available"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPatch424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsPatch500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}},"get":{"summary":"Retrieve a Payment Instrument","parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"tokenId","in":"path","description":"The TokenId of a Payment Instrument.","required":true,"type":"string","minimum":16,"maximum":32}],"tags":["PaymentInstruments"],"responses":{"200":{"description":"An existing Payment Instrument associated with the supplied tokenId has been returned.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"object","title":"tmsV1PaymentinstrumentsGet200Response","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"id":{"type":"string","readOnly":true,"example":"1234567890123456800","description":"Unique identification number assigned by CyberSource to the submitted request."},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["paymentInstrument"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"bankAccount":{"type":"object","properties":{"type":{"type":"string","example":"savings","description":"Type of Bank Account."}}},"card":{"type":"object","properties":{"expirationMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card expiration month."},"expirationYear":{"type":"string","example":"2022","minimum":1900,"maximum":2099,"description":"Credit card expiration year."},"type":{"type":"string","example":"visa","description":"Credit card brand.","enum":["visa","mastercard","american express","discover","diners club","carte blanche","jcb","optima","twinpay credit","twinpay debit","walmart","enroute","lowes consumer","home depot consumer","mbna","dicks sportswear","casual corner","sears","jal","disney","maestro uk domestic","sams club consumer","sams club business","nicos","bill me later","bebe","restoration hardware","delta online","solo","visa electron","dankort","laser","carte bleue","carta si","pinless debit","encoded account","uatp","household","maestro international","ge money uk","korean cards","style","jcrew","payease china processing ewallet","payease china processing bank transfer","meijer private label","hipercard","aura","redecard","orico","elo","capital one private label","synchrony private label","china union pay"]},"issueNumber":{"type":"string","example":"01","minimum":0,"maximum":99,"description":"Credit card issue number."},"startMonth":{"type":"string","example":"12","minimum":1,"maximum":12,"description":"Credit card start month."},"startYear":{"type":"string","example":"12","minimum":1900,"maximum":2099,"description":"Credit card start year."},"useAs":{"type":"string","example":"pinless debit","description":"Card Use As Field. Supported value of \"pinless debit\" only. Only for use with Pinless Debit tokens."}}},"buyerInformation":{"type":"object","properties":{"companyTaxID":{"type":"string","example":"1234567890123456800","maximum":9,"description":"Company Tax ID."},"currency":{"type":"string","example":"USD","minimum":3,"maximum":3,"description":"Currency. Accepts input in the ISO 4217 standard, stores as ISO 4217 Alpha"},"dateOBirth":{"type":"string","example":"1960-12-30","description":"Date of birth YYYY-MM-DD."},"personalIdentification":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"1234567890","description":"Identification Number."},"type":{"type":"string","example":"driver license","description":"Type of personal identification."},"issuedBy":{"type":"object","properties":{"administrativeArea":{"type":"string","example":"CA","description":"State or province where the identification was issued."}}}}}}}},"billTo":{"type":"object","properties":{"firstName":{"type":"string","example":"John","maximum":60,"description":"Bill to First Name."},"lastName":{"type":"string","example":"Smith","maximum":60,"description":"Bill to Last Name."},"company":{"type":"string","example":"CyberSource","maximum":60,"description":"Bill to Company."},"address1":{"type":"string","example":"12 Main Street","maximum":60,"description":"Bill to Address Line 1."},"address2":{"type":"string","example":"20 My Street","maximum":60,"description":"Bill to Address Line 2."},"locality":{"type":"string","example":"Foster City","maximum":50,"description":"Bill to City."},"administrativeArea":{"type":"string","example":"CA","maximum":20,"description":"Bill to State."},"postalCode":{"type":"string","example":"90200","maximum":10,"description":"Bill to Postal Code."},"country":{"type":"string","example":"US","minimum":2,"maximum":3,"description":"Bill to Country. Accepts input in the ISO 3166-1 standard, stores as ISO 3166-1-Alpha-2"},"email":{"type":"string","example":"john.smith@example.com","maximum":320,"description":"Valid Bill to Email."},"phoneNumber":{"type":"string","example":"555123456","minimum":6,"maximum":32,"description":"Bill to Phone Number."}}},"processingInformation":{"type":"object","properties":{"billPaymentProgramEnabled":{"type":"boolean","example":true,"description":"Bill Payment Program Enabled."},"bankTransferOptions":{"type":"object","properties":{"SECCode":{"type":"string","example":"WEB","description":"Authorization method used for the transaction.(acceptable values are CCD, PPD, TEL, WEB)."}}}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"alternateName":{"type":"string","example":"Branch Name","description":"Alternate information for your business. This API field overrides the company entry description value in your CyberSource account."}}}}},"metaData":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}},"instrumentIdentifier":{"type":"object","properties":{"_links":{"type":"object","readOnly":true,"properties":{"self":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"ancestor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}},"successor":{"type":"object","properties":{"href":{"type":"string","example":"https://api.cybersource.com/tms/v1/instrumentidentifiers/1234567890123456789"}}}}},"object":{"type":"string","readOnly":true,"example":"instrumentIdentifier","description":"Describes type of token. For example: customer, paymentInstrument or instrumentIdentifier.","enum":["instrumentIdentifier"]},"state":{"type":"string","readOnly":true,"example":"ACTIVE","description":"Current state of the token.","enum":["ACTIVE","CLOSED"]},"id":{"type":"string","example":"1234567890123456789","minimum":16,"maximum":32,"description":"The id of the existing instrument identifier to be linked to the newly created payment instrument."},"card":{"type":"object","properties":{"number":{"type":"string","example":"1234567890987654","minimum":12,"maximum":19,"description":"Credit card number (PAN)."}}},"bankAccount":{"type":"object","properties":{"number":{"type":"string","example":"1234567890123456800","minimum":1,"maximum":19,"description":"Bank account number."},"routingNumber":{"type":"string","example":"123456789","minimum":1,"maximum":9,"description":"Routing number."}}},"processingInformation":{"type":"object","properties":{"authorizationOptions":{"type":"object","properties":{"initiator":{"type":"object","properties":{"merchantInitiatedTransaction":{"type":"object","properties":{"previousTransactionId":{"type":"string","example":"123456789012345","maximum":15,"description":"Previous Consumer Initiated Transaction Id."}}}}}}}}},"metadata":{"type":"object","readOnly":true,"properties":{"creator":{"type":"string","example":"merchantName","description":"The creator of the token."}}}}}}},"x-examples":{"application/json":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/paymentinstruments/5910683634E6B035E0539399D30A4B46"}},"id":"5910683634E6B035E0539399D30A4B46","object":"paymentInstrument","state":"ACTIVE","card":{"expirationMonth":11,"expirationYear":2020,"type":"visa","issueNumber":1,"startMonth":12,"startYear":2017},"buyerInformation":{"companyTaxID":12345,"currency":"USD"},"billTo":{"firstName":"John","lastName":"Smith","company":"Cybersource","address1":"1 My Apartment","address2":"20 My Street","locality":"San Francisco","administrativeArea":"CA","postalCode":90210,"country":"US","email":"ohn.smith@test.com","phoneNumber":"+44 289044795"},"processingInformation":{"billPaymentProgramEnabled":true},"metadata":{"creator":"user"},"_embedded":{"instrumentIdentifier":{"_links":{"self":{"href":"https://api.cybersource.com/tms/v1/instrumentidentifiers/58FEBAEFD2EEFCE1E0539399D30A7500"}},"id":"58FEBAEFD2EEFCE1E0539399D30A7500","object":"instrumentIdentifier","state":"ACTIVE","card":{"number":"424242XXXXXX4242"},"processingInformation":{"authorizationOptions":{"initiator":{"merchantInitiatedTransaction":{"previousTransactionId":123456789012345}}}},"metadata":{"creator":"user"}}}}}},"400":{"description":"Bad Request: e.g. A required header value could be missing.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsGet400Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"Missing Headers":{"errors":[{"type":"missingHeaders","message":"Missing header values"}]}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsGet403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"404":{"description":"Token Not Found: e.g. The tokenid may not exist or was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsGet404Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Token not found"}]}}},"410":{"description":"Token Not Available: e.g. The token has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsGet410Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notAvailable","message":"Token not available"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsGet424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsGet500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}},"delete":{"summary":"Delete a Payment Instrument","tags":["PaymentInstruments"],"parameters":[{"name":"profile-id","in":"header","description":"The id of a profile containing user specific TMS configuration.","required":true,"type":"string","minimum":36,"maximum":36},{"name":"tokenId","in":"path","description":"The TokenId of a Payment Instrument.","required":true,"type":"string","minimum":16,"maximum":32}],"responses":{"204":{"description":"An existing Payment Instrument associated with the supplied tokenId has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}}},"403":{"description":"Forbidden: e.g. The profile might not have permission to perform the token operation.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsDelete403Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"forbidden","message":"Request not permitted"}]}}},"404":{"description":"Token Not Found: e.g. The tokenid may not exist or was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsDelete404Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Token not found"}]}}},"410":{"description":"Token Not Available: e.g. The token has been deleted.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsDelete410Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notAvailable","message":"Token not available"}]}}},"424":{"description":"Failed Dependency: e.g. The profile represented by the profile-id may not exist or the profile-id was entered incorrectly.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsDelete424Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}},"examples":{"application/json":{"errors":[{"type":"notFound","message":"Profile not found"}]}}},"500":{"description":"Unexpected error.","headers":{"uniqueTransactionID":{"description":"A globally unique id associated with your request.","type":"string"}},"examples":{"application/json":{"errors":[{"type":"serverError","message":"Internal server error"}]}},"schema":{"type":"array","title":"tmsV1PaymentinstrumentsDelete500Response","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string","description":"The detailed message related to the type stated above."},"details":{"type":"object","properties":{"name":{"type":"string","description":"The name of the field that threw the error."},"location":{"type":"string","description":"The location of the field that threw the error."}}}}}}}}}},"/tss/v2/transactions/{id}":{"get":{"summary":"Retrieve a Transaction","description":"Include the Request ID in the GET request to retrieve the transaction details.","tags":["TransactionDetails"],"operationId":"getTransaction","parameters":[{"name":"id","in":"path","description":"Request ID.\n","required":true,"type":"string"}],"x-example":{"example0":{"summary":"Retrieve a Transaction","value":[]}},"responses":{"200":{"description":"Successful response.","schema":{"title":"tssV2TransactionsGet200Response","type":"object","properties":{"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"rootId":{"type":"string","maxLength":26,"description":"Payment Request Id"},"reconciliationId":{"type":"string","maxLength":60,"description":"The reconciliation id for the submitted transaction. This value is not returned for all processors.\n"},"merchantId":{"type":"string","description":"The description for this field is not available."},"status":{"type":"string","description":"The status of the submitted transaction."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"applicationInformation":{"type":"object","properties":{"status":{"type":"string","description":"The status of the submitted transaction."},"reasonCode":{"type":"string","description":"The description for this field is not available."},"rCode":{"type":"string","description":"The description for this field is not available."},"rFlag":{"type":"string","description":"The description for this field is not available."},"applications":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The description for this field is not available."},"status":{"type":"string","description":"The description for this field is not available."},"reasonCode":{"type":"string","description":"The description for this field is not available."},"rCode":{"type":"string","description":"The description for this field is not available."},"rFlag":{"type":"string","description":"The description for this field is not available."},"reconciliationId":{"type":"string","description":"The description for this field is not available."},"rMessage":{"type":"string","description":"The description for this field is not available."},"returnCode":{"type":"string","description":"The description for this field is not available."}}}}}},"buyerInformation":{"type":"object","properties":{"merchantCustomerId":{"type":"string","maxLength":100,"description":"Your identifier for the customer.\n\nFor processor-specific information, see the customer_account_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"hashedPassword":{"type":"string","maxLength":100,"description":"The description for this field is not available.\n"}}},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"applicationVersion":{"type":"string","description":"The description for this field is not available."},"applicationName":{"type":"string","description":"The application name of client which is used to submit the request."},"applicationUser":{"type":"string","description":"The description for this field is not available."},"comments":{"type":"string","description":"The description for this field is not available."}}},"consumerAuthenticationInformation":{"type":"object","properties":{"eciRaw":{"type":"string","maxLength":2,"description":"Raw electronic commerce indicator (ECI)."},"cavv":{"type":"string","maxLength":40,"description":"Cardholder authentication verification value (CAVV)."},"xid":{"type":"string","maxLength":40,"description":"Transaction identifier."},"transactionId":{"type":"string","description":"Payer auth Transaction identifier."}}},"deviceInformation":{"type":"object","properties":{"ipAddress":{"type":"string","maxLength":15,"description":"IP address of the customer."},"hostName":{"type":"string","maxLength":60,"description":"DNS resolved hostname from above _ipAddress_."},"cookiesAccepted":{"type":"string","description":"The description for this field is not available."}}},"errorInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The description for this field is not available."},"message":{"type":"string","description":"The description for this field is not available."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}},"installmentInformation":{"type":"object","properties":{"numberOfInstallments":{"type":"string","description":"Number of Installments."}}},"fraudMarkingInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The description for this field is not available."}}},"merchantDefinedInformation":{"type":"array","description":"The description for this field is not available.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":50,"description":"The description for this field is not available."},"value":{"type":"string","maxLength":255,"description":"The description for this field is not available."}}}},"merchantInformation":{"type":"object","properties":{"merchantDescriptor":{"type":"object","properties":{"name":{"type":"string","maxLength":23,"description":"For the descriptions, used-by information, data types, and lengths for these fields, see Merchant Descriptors\nin [Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n\nFor Payouts:\n* Paymentech (22)\n"}}}}},"orderInformation":{"type":"object","properties":{"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"middelName":{"type":"string","maxLength":60,"description":"Customer\u2019s middle name.\n"},"nameSuffix":{"type":"string","maxLength":60,"description":"Customer\u2019s name suffix.\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the billing street address as it appears on the credit card issuer\u2019s records.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address1 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"address2":{"type":"string","maxLength":60,"description":"Additional address information.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_address2 field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"locality":{"type":"string","maxLength":50,"description":"City of the billing address.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_city field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the billing address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_state field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the billing address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the bill_zip field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"company":{"type":"string","maxLength":60,"description":"Name of the customer\u2019s company.\n\nFor processor-specific information, see the company_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"email":{"type":"string","maxLength":255,"description":"Customer's email address, including the full domain name.\n\nFor processor-specific information, see the customer_email field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"title":{"type":"string","maxLength":60,"description":"Title.\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"shipTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"First name of the recipient.\n\n**Processor specific maximum length**\n\n- Litle: 25\n- All other processors: 60\n"},"lastName":{"type":"string","maxLength":60,"description":"Last name of the recipient.\n\n**Processor specific maximum length**\n\n- Litle: 25\n- All other processors: 60\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the shipping address."},"address2":{"type":"string","maxLength":60,"description":"Second line of the shipping address."},"locality":{"type":"string","maxLength":50,"description":"City of the shipping address."},"administrativeArea":{"type":"string","maxLength":2,"description":"State or province of the shipping address. Use the State, Province, and Territory Codes for the United States\nand Canada.\n"},"postalCode":{"type":"string","maxLength":10,"description":"Postal code for the shipping address. The postal code must consist of 5 to 9 digits.\n\nWhen the billing country is the U.S., the 9-digit postal code must follow this format:\n[5 digits][dash][4 digits]\n\nExample 12345-6789\n\nWhen the billing country is Canada, the 6-digit postal code must follow this format:\n[alpha][numeric][alpha][space][numeric][alpha][numeric]\n\nExample A1B 2C3\n"},"company":{"type":"string","maxLength":60,"description":"Name of the customer\u2019s company.\n\nFor processor-specific information, see the company_name field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the shipping address. Use the two character ISO Standard Country Codes."},"phoneNumber":{"type":"string","maxLength":15,"description":"Phone number for the shipping address."}}},"lineItems":{"type":"array","description":"Transaction Line Item data.","items":{"type":"object","properties":{"productCode":{"type":"string","maxLength":255,"description":"Type of product. This value is used to determine the category that the product is in: electronic, handling,\nphysical, service, or shipping. The default value is **default**.\n\nFor a payment, when you set this field to a value other than default or any of the values related to\nshipping and handling, below fields _quantity_, _productName_, and _productSKU_ are required.\n"},"productName":{"type":"string","maxLength":255,"description":"For PAYMENT and CAPTURE API, this field is required when above _productCode_ is not **default** or one of the\nvalues related to shipping and handling.\n"},"productSku":{"type":"string","maxLength":255,"description":"Identification code for the product. For PAYMENT and CAPTURE API, this field is required when above\n_productCode_ is not **default** or one of the values related to shipping and/or handling.\n"},"taxAmount":{"type":"string","maxLength":15,"description":"Total tax to apply to the product. This value cannot be negative. The tax amount and the offer amount must\nbe in the same currency. The tax amount field is additive.\n\nThe following example uses a two-exponent currency such as USD:\n\n1. You include each line item in your request.\n..- 1st line item has amount=10.00, quantity=1, and taxAmount=0.80\n..- 2nd line item has amount=20.00, quantity=1, and taxAmount=1.60\n2. The total amount authorized will be 32.40, not 30.00 with 2.40 of tax included.\n\nThis field is frequently used for Level II and Level III transactions.\n"},"quantity":{"type":"number","minimum":1,"maximum":9999999999,"description":"For a payment or capture, this field is required when _productCode_ is not **default** or one of the values\nrelated to shipping and handling.\n","default":1},"unitPrice":{"type":"string","maxLength":15,"description":"Per-item price of the product. This value cannot be negative. You can include a decimal point (.), but you\ncannot include any other special characters. CyberSource truncates the amount to the correct number of decimal\nplaces.\n\nFor processor-specific information, see the amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"fulfillmentType":{"type":"string","description":"The description for this field is not available."}}}},"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"},"taxAmount":{"type":"string","maxLength":12,"description":"Total tax amount for all the items in the order.\n\nFor processor-specific information, see the total_tax_amount field in\n[Level II and Level III Processing Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/Level_2_3_SCMP_API/html)\n"},"authorizedAmount":{"type":"string","maxLength":15,"description":"Amount that was authorized.\n"}}},"shippingDetails":{"type":"object","properties":{"giftWrap":{"type":"boolean","description":"The description for this field is not available."},"shippingMethod":{"type":"string","maxLength":10,"description":"Shipping method for the product. Possible values:\n\n - lowcost: Lowest-cost service\n - sameday: Courier or same-day service\n - oneday: Next-day or overnight service\n - twoday: Two-day service\n - threeday: Three-day service\n - pickup: Store pick-up\n - other: Other shipping method\n - none: No shipping method because product is a service or subscription\n"}}}}},"paymentInformation":{"type":"object","properties":{"paymentType":{"type":"object","properties":{"name":{"type":"string","description":"The description for this field is not available."},"type":{"type":"string","description":"The description for this field is not available."},"subType":{"type":"string","description":"The description for this field is not available."},"method":{"type":"string","description":"The description for this field is not available."},"fundingSource":{"type":"string","description":"The description for this field is not available."},"fundingSourceAffiliation":{"type":"string","description":"The description for this field is not available."},"credential":{"type":"string","description":"The description for this field is not available."}}},"customer":{"type":"object","properties":{"customerId":{"type":"string","maxLength":26,"description":"Unique identifier for the customer's card and billing information."}}},"card":{"type":"object","properties":{"suffix":{"type":"string","maxLength":4,"description":"Last four digits of the cardholder\u2019s account number. This field is returned only for tokenized transactions.\nYou can use this value on the receipt that you give to the cardholder.\n"},"prefix":{"type":"string","maxLength":6,"description":"The description for this field is not available."},"expirationMonth":{"type":"string","maxLength":2,"description":"Two-digit month in which the credit card expires. `Format: MM`. Possible values: 01 through 12.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 12.\n\nFor processor-specific information, see the customer_cc_expmo field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"expirationYear":{"type":"string","maxLength":4,"description":"Four-digit year in which the credit card expires. `Format: YYYY`.\n\n**Encoded Account Numbers**\n\nFor encoded account numbers (_type_=039), if there is no expiration date on the card, use 2021.\n\nFor processor-specific information, see the customer_cc_expyr field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"startMonth":{"type":"string","maxLength":2,"description":"Month of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: MM`. Possible values: 01 through 12.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"},"startYear":{"type":"string","maxLength":4,"description":"Year of the start of the Maestro (UK Domestic) card validity period. Do not include the field, even with a\nblank value, if the card is not a Maestro (UK Domestic) card. `Format: YYYY`.\n\nThe start date is not required for Maestro (UK Domestic) transactions.\n"},"issueNumber":{"type":"string","maxLength":5,"description":"Number of times a Maestro (UK Domestic) card has been issued to the account holder. The card might or might\nnot have an issue number. The number can consist of one or two digits, and the first digit might be a zero.\nWhen you include this value in your request, include exactly what is printed on the card. A value of 2 is\ndifferent than a value of 02. Do not include the field, even with a blank value, if the card is not a\nMaestro (UK Domestic) card.\n\nThe issue number is not required for Maestro (UK Domestic) transactions.\n"},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"},"accountEncoderId":{"type":"string","maxLength":3,"description":"Identifier for the issuing bank that provided the customer\u2019s encoded account number. Contact your processor\nfor the bank\u2019s ID.\n"},"useAs":{"type":"string","maxLength":2,"description":"Flag that specifies the type of account associated with the card. The cardholder provides this information\nduring the payment process.\n\n**Cielo** and **Comercio Latino**\n\nPossible values:\n\n - CREDIT: Credit card\n - DEBIT: Debit card\n\nThis field is required for:\n - Debit transactions on Cielo and Comercio Latino.\n - Transactions with Brazilian-issued cards on CyberSource through VisaNet.\n"}}},"invoice":{"type":"object","properties":{"number":{"type":"string","description":"Invoice Number."},"barcodeNumber":{"type":"string","description":"Barcode Number."},"expirationDate":{"type":"string","description":"Expiration Date."}}},"bank":{"type":"object","properties":{"routingNumber":{"type":"string","description":"The description for this field is not available."},"branchCode":{"type":"string","description":"The description for this field is not available."},"swiftCode":{"type":"string","description":"The description for this field is not available."},"bankCode":{"type":"string","description":"The description for this field is not available."},"iban":{"type":"string","description":"The description for this field is not available."},"account":{"type":"object","properties":{"suffix":{"type":"string","description":"The description for this field is not available."},"prefix":{"type":"string","description":"The description for this field is not available."},"checkNumber":{"type":"string","description":"The description for this field is not available."},"type":{"type":"string","description":"The description for this field is not available."},"name":{"type":"string","description":"The description for this field is not available."},"checkDigit":{"type":"string","description":"The description for this field is not available."},"encoderId":{"type":"string","description":"The description for this field is not available."}}},"mandate":{"type":"object","properties":{"referenceNumber":{"type":"string","description":"The description for this field is not available."},"recurringType":{"type":"string","description":"The description for this field is not available."},"id":{"type":"string","description":"The description for this field is not available."}}}}},"accountFeatures":{"type":"object","properties":{"balanceAmount":{"type":"string","maxLength":12,"description":"Remaining balance on the account.\n"},"previousBalanceAmount":{"type":"string","maxLength":12,"description":"Remaining balance on the account.\n"},"currency":{"type":"string","maxLength":5,"description":"Currency of the remaining balance on the account. For the possible values, see the ISO Standard Currency Codes.\n"}}}}},"processingInformation":{"type":"object","properties":{"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"commerceIndicator":{"type":"string","maxLength":20,"description":"Type of transaction. Some payment card companies use this information when determining discount rates. When you\nomit this field for **Ingenico ePayments**, the processor uses the default transaction type they have on file\nfor you instead of the default value listed here.\n"},"businessApplicationId":{"type":"string","description":"The description for this field is not available."},"authorizationOptions":{"type":"object","properties":{"authType":{"type":"string","maxLength":15,"description":"Authorization type. Possible values:\n\n - **AUTOCAPTURE**: automatic capture.\n - **STANDARDCAPTURE**: standard capture.\n - **VERBAL**: forced capture. Include it in the payment request for a forced capture. Include it in the capture\n request for a verbal payment.\n\nFor processor-specific information, see the auth_type field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"bankTransferOptions":{"type":"object","properties":{"secCode":{"type":"string","description":"The description for this field is not available."}}}}},"processorInformation":{"type":"object","properties":{"processor":{"type":"object","properties":{"name":{"type":"string","maxLength":30,"description":"Name of the Processor.\n"}}},"transactionId":{"type":"string","maxLength":50,"description":"Network transaction identifier (TID). You can use this value to identify a specific transaction when you are\ndiscussing the transaction with your processor. Not all processors provide this value.\n"},"networkTransactionId":{"type":"string","description":"The description for this field is not available."},"responseId":{"type":"string","description":"The description for this field is not available."},"providerTransactionId":{"type":"string","description":"The description for this field is not available."},"approvalCode":{"type":"string","description":"Authorization code. Returned only when the processor returns this value.\n"},"responseCode":{"type":"string","maxLength":10,"description":"For most processors, this is the error message sent directly from the bank. Returned only when the processor\nreturns this value.\n\nImportant Do not use this field to evaluate the result of the authorization.\n"},"avs":{"type":"object","properties":{"code":{"type":"string","maxLength":1,"description":"AVS result code.\n"},"codeRaw":{"type":"string","maxLength":10,"description":"AVS result code sent directly from the processor. Returned only when the processor returns this value.\nImportant Do not use this field to evaluate the result of AVS. Use for debugging purposes only.\n"}}},"cardVerification":{"type":"object","properties":{"resultCode":{"type":"string","maxLength":1,"description":"CVN result code.\n"}}},"achVerification":{"type":"object","properties":{"resultCode":{"type":"string","maxLength":1,"description":"The description for this field is not available..\n"},"resultCodeRaw":{"type":"string","maxLength":10,"description":"The description for this field is not available.\n"}}},"electronicVerificationResults":{"type":"object","properties":{"email":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s email address.\n"},"emailRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s email address."},"name":{"type":"string","maxLength":30,"description":"The description for this field is not available.\n"},"nameRaw":{"type":"string","maxLength":30,"description":"The description for this field is not available."},"phoneNumber":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s phone number.\n"},"phoneNumberRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s phone number."},"street":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s street address.\n"},"streetRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s street address."},"postalCode":{"type":"string","maxLength":1,"description":"Mapped Electronic Verification response code for the customer\u2019s postal code.\n"},"postalCodeRaw":{"type":"string","maxLength":1,"description":"Raw Electronic Verification response code from the processor for the customer\u2019s postal code."}}}}},"pointOfSaleInformation":{"type":"object","properties":{"entryMode":{"type":"string","maxLength":11,"description":"Method of entering credit card information into the POS terminal. Possible values:\n\n - contact: Read from direct contact with chip card.\n - contactless: Read from a contactless interface using chip data.\n - keyed: Manually keyed into POS terminal.\n - msd: Read from a contactless interface using magnetic stripe data (MSD).\n - swiped: Read from credit card magnetic stripe.\n\nThe contact, contactless, and msd values are supported only for EMV transactions.\n* Applicable only for CTV for Payouts.\n"},"terminalCapability":{"type":"integer","minimum":1,"maximum":5,"description":"POS terminal\u2019s capability. Possible values:\n\n - 1: Terminal has a magnetic stripe reader only.\n - 2: Terminal has a magnetic stripe reader and manual entry capability.\n - 3: Terminal has manual entry capability only.\n - 4: Terminal can read chip cards.\n - 5: Terminal can read contactless chip cards.\n\nThe values of 4 and 5 are supported only for EMV transactions.\n* Applicable only for CTV for Payouts. \n"}}},"riskInformation":{"type":"object","properties":{"profile":{"type":"object","properties":{"name":{"type":"string","description":"The description for this field is not available."},"decision":{"type":"string","description":"The description for this field is not available."}}},"rules":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The description for this field is not available."},"decision":{"type":"string","description":"The description for this field is not available."}}}},"passiveProfile":{"type":"object","properties":{"name":{"type":"string","description":"The description for this field is not available."},"decision":{"type":"string","description":"The description for this field is not available."}}},"passiveRules":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The description for this field is not available."},"decision":{"type":"string","description":"The description for this field is not available."}}}},"score":{"type":"object","properties":{"factorCodes":{"type":"array","description":"Array of factor codes.","items":{"type":"string","description":"Represents a factor code."}},"result":{"type":"integer","description":"The description for this field is not available.\n"}}},"localTime":{"type":"string","description":"Time that the transaction was submitted in local time.."}}},"senderInformation":{"type":"object","properties":{"referenceNumber":{"type":"string","maxLength":19,"description":"Reference number generated by you that uniquely identifies the sender."}}},"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}}},"example":{"id":"5330579740206278601009","rootId":"5330571038726320201013","reconciliationId":"53703847LK9LPPXY","merchantId":"string","status":"PENDING","submitTimeUtc":"2018-07-31T17:26:14Z","applicationInformation":{"status":"PENDING","reasonCode":"100","rCode":"string","rFlag":"string","applications":[{"name":"ics_bill","status":"PENDING","reasonCode":"100","rCode":"string","rFlag":"string","reconciliationId":"53703847LK9LPPXY","rMessage":"Request was processed successfully.","returnCode":"1260000"}]},"buyerInformation":{"merchantCustomerId":"123456","hashedPassword":"fhjfhj"},"clientReferenceInformation":{"code":"ECERT001","applicationVersion":"1.0","applicationName":"string","applicationUser":"ng_paymentech","comments":"test comment"},"consumerAuthenticationInformation":{"eciRaw":"1234","cavv":"12345","xid":"12345678","transactionId":"string"},"deviceInformation":{"ipAddress":"1.10.10.10","hostName":"cybs test","cookiesAccepted":"no"},"errorInformation":{"reason":"string","message":"string","details":[{"field":"string","reason":"string"}]},"installmentInformation":{"numberOfInstallments":0},"fraudMarkingInformation":{"reason":"string"},"merchantDefinedInformation":[{"key":"string","value":"string"}],"merchantInformation":{"merchantDescriptor":{"name":"ng_paymentech"}},"orderInformation":{"billTo":{"firstName":"JAMES","lastName":"DOUGH","middleName":"ROY","nameSuffix":"Mr","address1":"600 Morgan Falls Road","address2":"Room 2-2123","locality":"Atlanta","administrativeArea":"GA","postalCode":"30350","company":"cybersource","email":"jdough@cybersource.com","country":"US","title":"Manager","phoneNumber":"6509656111"},"shipTo":{"firstName":"Test","lastName":"TSS","address1":"201S.DivisionSt._1","address2":"Suite500","locality":"Austin","administrativeArea":"TX","postalCode":"78750","company":"cybs","country":"US","phoneNumber":"5120000000"},"lineItems":[{"productCode":"string","productName":"string","productSku":"string","taxAmount":"string","quantity":123,"unitPrice":"string","fulfillmentType":"string"}],"amountDetails":{"totalAmount":"100","currency":"USD","taxAmount":"5","authorizedAmount":"100"},"shippingDetails":{"giftWrap":"none","shippingMethod":"string"}},"paymentInformation":{"paymentType":{"name":"paymentProcessor1234","type":"credit card","subType":"V1","method":"string","fundingSource":"string","fundingSourceAffiliation":"string","credential":"string"},"customer":{"customerId":"string"},"card":{"suffix":"1111","prefix":"123","expirationMonth":"10","expirationYear":"2017","startMonth":"string","startYear":"string","issueNumber":"string","type":"credit card","accountEncoderId":"string","useAs":"string"},"invoice":{"number":"string","barcodeNumber":"string","expirationDate":"string"},"bank":{"routingNumber":"string","branchCode":"string","swiftCode":"string","bankCode":"string","iban":"string","account":{"suffix":"2222","prefix":"123","checkNumber":"123456","type":"string","name":"string","checkDigit":"string","encoderId":"string"},"mandate":{"referenceNumber":"string","recurringType":"string","id":"string"}},"accountFeatures":{"balanceAmount":"string","previousBalanceAmount":"string","currency":"string"}},"processingInformation":{"paymentSolution":"Visa","commerceIndicator":"7","businessApplicationId":"string","authorizationOptions":{"authType":"0"},"bankTransferOptions":{"secCode":"string"}},"processorInformation":{"processor":{"name":"paymentProcessor1234"},"transactionId":"processortransactionid123","networkTransactionId":"networktransactionid67890","responseId":"string","providerTransactionId":"string","approvalCode":"authcode1234567","responseCode":"responsecode12345678","avs":{"code":"ARM","codeRaw":"avsResults"},"cardVerification":{"resultCode":"Y"},"achVerification":{"resultCode":"rspcodmap","resultCodeRaw":"responsecode12345678"},"electronicVerificationResults":{"email":"email@email.com","emailRaw":"emailRaw12","name":"ename","nameRaw":"enameRaw12","phoneNumber":"01179","phoneNumberRaw":"9925551608","street":"123 street","streetRaw":"SteertRaw12","postalCode":"78717","postalCodeRaw":"1166678717"}},"pointOfSaleInformation":{"entryMode":"posentrymode1234512","terminalCapability":"integer"},"riskInformation":{"profile":{"name":"string","decision":"string"},"rules":[{"name":"string","decision":"string"}],"passiveProfile":{"name":"string","decision":"string"},"passiveRules":[{"name":"string","decision":"string"}],"localTime":"string","score":{"factorCodes":["string"],"result":"integer"}},"senderInformation":{"referenceNumber":"senderRefNumber1"},"_links":{"self":{"href":"https://sl73paysvapq002.visa.com:2031/payment/tss/v2/transactions/5330579740206278601009","method":"GET"}}}}},"404":{"description":"The specified resource not found in the system."},"500":{"description":"Unexpected server error."}}}},"/tss/v2/searches":{"post":{"summary":"Create a search request","description":"Create a search request.\n","tags":["SearchTransactions"],"operationId":"createSearch","parameters":[{"name":"createSearchRequest","in":"body","required":true,"schema":{"title":"tssV2TransactionsPostResponse","type":"object","properties":{"save":{"type":"boolean","description":"save or not save."},"name":{"type":"string","description":"The description for this field is not available.\n"},"timezone":{"type":"string","description":"Time Zone."},"query":{"type":"string","description":"transaction search query string."},"offset":{"type":"integer","description":"offset."},"limit":{"type":"integer","description":"limit on number of results."},"sort":{"type":"string","description":"A comma separated list of the following form - fieldName1 asc or desc, fieldName2 asc or desc, etc."}}}}],"x-example":{"example0":{"summary":"Create a search request","value":{"save":"false","name":"TSS search","timezone":"America/Chicago","query":"clientReferenceInformation.code:12345","offset":0,"limit":100,"sort":"id:asc, submitTimeUtc:asc"}}},"responses":{"201":{"description":"Successful response.","schema":{"title":"tssV2TransactionsPost201Response","type":"object","properties":{"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"save":{"type":"boolean","description":"save or not save."},"name":{"type":"string","description":"The description for this field is not available.\n"},"timezone":{"type":"string","description":"Time Zone."},"query":{"type":"string","description":"transaction search query string."},"offset":{"type":"integer","description":"offset."},"limit":{"type":"integer","description":"limit on number of results."},"sort":{"type":"string","description":"A comma separated list of the following form - fieldName1 asc or desc, fieldName2 asc or desc, etc."},"count":{"type":"integer","description":"Results for this page, this could be below the limit."},"totalCount":{"type":"integer","description":"total number of results."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"_embedded":{"type":"object","properties":{"transactionSummaries":{"type":"array","description":"transaction search summary","items":{"type":"object","properties":{"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"merchantId":{"type":"string","description":"The description for this field is not available."},"applicationInformation":{"type":"object","properties":{"status":{"type":"string","description":"The status of the submitted transaction."},"reasonCode":{"type":"string","description":"The description for this field is not available."},"rCode":{"type":"string","description":"The description for this field is not available."},"rFlag":{"type":"string","description":"The description for this field is not available."},"applications":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The description for this field is not available."},"status":{"type":"string","description":"The description for this field is not available."},"reasonCode":{"type":"string","description":"The description for this field is not available."},"rCode":{"type":"string","description":"The description for this field is not available."},"rFlag":{"type":"string","description":"The description for this field is not available."},"reconciliationId":{"type":"string","description":"The description for this field is not available."},"rMessage":{"type":"string","description":"The description for this field is not available."},"returnCode":{"type":"string","description":"The description for this field is not available."}}}}}},"buyerInformation":{"type":"object","properties":{"merchantCustomerId":{"type":"string","maxLength":100,"description":"Your identifier for the customer.\n\nFor processor-specific information, see the customer_account_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"applicationName":{"type":"string","description":"The application name of client which is used to submit the request."},"applicationUser":{"type":"string","description":"The description for this field is not available."}}},"consumerAuthenticationInformation":{"type":"object","properties":{"xid":{"type":"string","maxLength":40,"description":"Transaction identifier."},"transactionId":{"type":"string","description":"Payer auth Transaction identifier."}}},"deviceInformation":{"type":"object","properties":{"ipAddress":{"type":"string","maxLength":15,"description":"IP address of the customer."}}},"fraudMarkingInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The description for this field is not available."}}},"merchantDefinedInformation":{"type":"array","description":"The description for this field is not available.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":50,"description":"The description for this field is not available."},"value":{"type":"string","maxLength":255,"description":"The description for this field is not available."}}}},"merchantInformation":{"type":"object","properties":{"resellerId":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."}}},"orderInformation":{"type":"object","properties":{"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"email":{"type":"string","maxLength":255,"description":"Customer's email address, including the full domain name.\n\nFor processor-specific information, see the customer_email field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"shipTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"First name of the recipient.\n\n**Processor specific maximum length**\n\n- Litle: 25\n- All other processors: 60\n"},"lastName":{"type":"string","maxLength":60,"description":"Last name of the recipient.\n\n**Processor specific maximum length**\n\n- Litle: 25\n- All other processors: 60\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the shipping address."},"country":{"type":"string","maxLength":2,"description":"Country of the shipping address. Use the two character ISO Standard Country Codes."},"phoneNumber":{"type":"string","maxLength":15,"description":"Phone number for the shipping address."}}},"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}}}},"paymentInformation":{"type":"object","properties":{"paymentMethod":{"type":"object","properties":{"type":{"type":"string","description":"The description for this field is not available."}}},"customer":{"type":"object","properties":{"customerId":{"type":"string","maxLength":26,"description":"Unique identifier for the customer's card and billing information."}}},"card":{"type":"object","properties":{"suffix":{"type":"string","maxLength":4,"description":"Last four digits of the cardholder\u2019s account number. This field is returned only for tokenized transactions.\nYou can use this value on the receipt that you give to the cardholder.\n"},"prefix":{"type":"string","maxLength":6,"description":"The description for this field is not available."},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"}}}}},"processingInformation":{"type":"object","properties":{"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"businessApplicationId":{"type":"string","description":"The description for this field is not available."}}},"processorInformation":{"type":"object","properties":{"processor":{"type":"object","properties":{"name":{"type":"string","maxLength":30,"description":"Name of the Processor.\n"}}}}},"pointOfSaleInformation":{"type":"object","properties":{"terminalId":{"type":"string","maxLength":8,"description":"Identifier for the terminal at your retail location. You can define this value yourself, but consult the\nprocessor for requirements.\n\nFor Payouts: This field is applicable for CtV.\n"},"terminalSerialNumber":{"type":"string","description":"The description for this field is not available."},"deviceId":{"type":"string","description":"The description for this field is not available."},"partner":{"type":"object","properties":{"originalTransactionId":{"type":"string","maxLength":50,"description":"Network transaction identifier (TID). You can use this value to identify a specific transaction when you are\ndiscussing the transaction with your processor. Not all processors provide this value.\n"}}}}},"riskInformation":{"type":"object","properties":{"providers":{"type":"object","properties":{"fingerprint":{"type":"object","properties":{"true_ipaddress":{"type":"string","maxLength":255,"description":"The description for this field is not available."},"hash":{"type":"string","maxLength":255,"description":"The description for this field is not available."},"smartId":{"type":"string","maxLength":255,"description":"The description for this field is not available."}}}}}}},"_links":{"type":"object","properties":{"transactionDetail":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}}}}}}},"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}}},"example":{"id":"87e1e4bd-cac2-49b1-919a-4d5e29a2e55d","save":"false","name":"Search By Code","timezone":"America/Chicago","query":"clientReferenceInformation.code:12345","offset":0,"limit":2000,"sort":"id:asc, submitTimeUtc:asc","count":22,"totalCount":22,"submitTimeUtc":"2018-09-18T16:59:28Z","_embedded":{"transactionSummaries":[{"id":"5217848115816817001541","submitTimeUtc":"2018-03-23T06:00:11Z","merchantId":"sandeep_wf","applicationInformation":{"status":"string","reasonCode":"string","rCode":"string","rFlag":"string","applications":[{"name":"ics_service_fee_calculate","status":"string","reasonCode":"string","rCode":"string","rFlag":"string","reconciliationId":"string","rMessage":"string","returnCode":"string"}]},"buyerInformation":{"merchantCustomerId":"123456"},"clientReferenceInformation":{"code":"12345","applicationName":"Service Fee Request","applicationUser":"sandeep_wf"},"consumerAuthenticationInformation":{"xid":"12345678","transactionId":"string"},"deviceInformation":{"ipAddress":"1.10.10.10"},"fraudMarkingInformation":{"reason":"fraud txn"},"merchantDefinedInformation":[{"key":"string","value":"string"}],"merchantInformation":{"resellerId":"wfbmcp"},"orderInformation":{"billTo":{"firstName":"Test","lastName":"TSS","email":"null@cybersource.com","country":"US","phoneNumber":"5120000000"},"shipTo":{"firstName":"Test","lastName":"TSS","address1":"201S.DivisionSt._1","country":"US","phoneNumber":"5120000000"},"amountDetails":{"totalAmount":"100.00","currency":"USD"}},"paymentInformation":{"paymentmethod":{"type":"credit card"},"customer":{"customerId":"12345"},"card":{"suffix":"1111","prefix":"123456","type":"credit card"}},"processingInformation":{"paymentSolution":"xyz","businessApplicationId":"string"},"processorInformation":{"processor":{"name":"FirstData"}},"pointOfSaleInformation":{"terminalId":"1","terminalSerialNumber":"123111123","deviceId":"asfaf12312313","partner":{"originalTransactionId":"131231414414"}},"riskInformation":{"providers":{"fingerprint":{"true_ipaddress":"1.101.102.112","hash":"tuWmt8Ubw0EAybBF3wrZcEqIcZsLr8YPldTQDUxAg2k=","smart_id":"23442fdadfa"}}},"_links":{"transactionDetail":{"href":"https://sl73paysvapq002.visa.com:2031/payment/tss/v2/transactions/5217848115816817001541","method":"GET"}}}]},"_links":{"self":{"href":"https://sl73paysvapq002.visa.com:2031/payment/tss/v2/searches/87e1e4bd-cac2-49b1-919a-4d5e29a2e55d","method":"GET"}}}}},"400":{"description":"Invalid request.","schema":{"title":"tssV2TransactionsPost400Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"502":{"description":"Unexpected system error or system timeout.","schema":{"title":"tssV2TransactionsPost502Response","type":"object","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["SERVER_ERROR"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["SYSTEM_ERROR","SERVER_TIMEOUT","SERVICE_TIMEOUT","PROCESSOR_TIMEOUT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."}}}}}}},"/tss/v2/searches/{id}":{"get":{"summary":"Get Search results","description":"Include the Search ID in the GET request to retrieve the search results.","tags":["SearchTransactions"],"operationId":"getSearch","parameters":[{"name":"id","in":"path","description":"Search ID.","required":true,"type":"string"}],"x-example":{"example0":{"summary":"Get Search results","value":[]}},"responses":{"200":{"description":"Successful response.","schema":{"title":"tssV2SearchesGet200Response","type":"object","properties":{"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"save":{"type":"boolean","description":"save or not save."},"name":{"type":"string","description":"The description for this field is not available.\n"},"timezone":{"type":"string","description":"Time Zone."},"query":{"type":"string","description":"transaction search query string."},"offset":{"type":"integer","description":"offset."},"limit":{"type":"integer","description":"limit on number of results."},"sort":{"type":"string","description":"A comma separated list of the following form - fieldName1 asc or desc, fieldName2 asc or desc, etc."},"count":{"type":"integer","description":"Results for this page, this could be below the limit."},"totalCount":{"type":"integer","description":"total number of results."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"_embedded":{"type":"object","properties":{"transactionSummaries":{"type":"array","description":"transaction search summary","items":{"type":"object","properties":{"id":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."},"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"merchantId":{"type":"string","description":"The description for this field is not available."},"applicationInformation":{"type":"object","properties":{"status":{"type":"string","description":"The status of the submitted transaction."},"reasonCode":{"type":"string","description":"The description for this field is not available."},"rCode":{"type":"string","description":"The description for this field is not available."},"rFlag":{"type":"string","description":"The description for this field is not available."},"applications":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The description for this field is not available."},"status":{"type":"string","description":"The description for this field is not available."},"reasonCode":{"type":"string","description":"The description for this field is not available."},"rCode":{"type":"string","description":"The description for this field is not available."},"rFlag":{"type":"string","description":"The description for this field is not available."},"reconciliationId":{"type":"string","description":"The description for this field is not available."},"rMessage":{"type":"string","description":"The description for this field is not available."},"returnCode":{"type":"string","description":"The description for this field is not available."}}}}}},"buyerInformation":{"type":"object","properties":{"merchantCustomerId":{"type":"string","maxLength":100,"description":"Your identifier for the customer.\n\nFor processor-specific information, see the customer_account_id field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"clientReferenceInformation":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"description":"Client-generated order reference or tracking number. CyberSource recommends that you send a unique value for each\ntransaction so that you can perform meaningful searches for the transaction.\n"},"applicationName":{"type":"string","description":"The application name of client which is used to submit the request."},"applicationUser":{"type":"string","description":"The description for this field is not available."}}},"consumerAuthenticationInformation":{"type":"object","properties":{"xid":{"type":"string","maxLength":40,"description":"Transaction identifier."},"transactionId":{"type":"string","description":"Payer auth Transaction identifier."}}},"deviceInformation":{"type":"object","properties":{"ipAddress":{"type":"string","maxLength":15,"description":"IP address of the customer."}}},"fraudMarkingInformation":{"type":"object","properties":{"reason":{"type":"string","description":"The description for this field is not available."}}},"merchantDefinedInformation":{"type":"array","description":"The description for this field is not available.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":50,"description":"The description for this field is not available."},"value":{"type":"string","maxLength":255,"description":"The description for this field is not available."}}}},"merchantInformation":{"type":"object","properties":{"resellerId":{"type":"string","maxLength":26,"description":"An unique identification number assigned by CyberSource to identify the submitted request."}}},"orderInformation":{"type":"object","properties":{"billTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"Customer\u2019s first name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_firstname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"lastName":{"type":"string","maxLength":60,"description":"Customer\u2019s last name. This name must be the same as the name on the card.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nFor processor-specific information, see the customer_lastname field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"email":{"type":"string","maxLength":255,"description":"Customer's email address, including the full domain name.\n\nFor processor-specific information, see the customer_email field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"country":{"type":"string","maxLength":2,"description":"Country of the billing address. Use the two-character ISO Standard Country Codes.\n\nFor processor-specific information, see the bill_country field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"phoneNumber":{"type":"string","maxLength":15,"description":"Customer\u2019s phone number.\n\nFor Payouts: This field may be sent only for FDC Compass.\n\nCyberSource recommends that you include the country code when the order is from outside the U.S.\n\nFor processor-specific information, see the customer_phone field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"}}},"shipTo":{"type":"object","properties":{"firstName":{"type":"string","maxLength":60,"description":"First name of the recipient.\n\n**Processor specific maximum length**\n\n- Litle: 25\n- All other processors: 60\n"},"lastName":{"type":"string","maxLength":60,"description":"Last name of the recipient.\n\n**Processor specific maximum length**\n\n- Litle: 25\n- All other processors: 60\n"},"address1":{"type":"string","maxLength":60,"description":"First line of the shipping address."},"country":{"type":"string","maxLength":2,"description":"Country of the shipping address. Use the two character ISO Standard Country Codes."},"phoneNumber":{"type":"string","maxLength":15,"description":"Phone number for the shipping address."}}},"amountDetails":{"type":"object","properties":{"totalAmount":{"type":"string","maxLength":19,"description":"Grand total for the order. You can include a decimal point (.), but no other special\ncharacters. CyberSource truncates the amount to the correct number of decimal places.\n\n* CTV, FDCCompass, Paymentech (<= 12)\n\nFor processor-specific information, see the grand_total_amount field in\n[Credit Card Services Using the SCMP API.](http://apps.cybersource.com/library/documentation/dev_guides/CC_Svcs_SCMP_API/html)\n"},"currency":{"type":"string","maxLength":3,"description":"Currency used for the order. Use the three-character ISO Standard Currency Codes.\n\nFor an authorization reversal or a capture, you must use the same currency that you used in your request for Payment API.\n"}}}}},"paymentInformation":{"type":"object","properties":{"paymentMethod":{"type":"object","properties":{"type":{"type":"string","description":"The description for this field is not available."}}},"customer":{"type":"object","properties":{"customerId":{"type":"string","maxLength":26,"description":"Unique identifier for the customer's card and billing information."}}},"card":{"type":"object","properties":{"suffix":{"type":"string","maxLength":4,"description":"Last four digits of the cardholder\u2019s account number. This field is returned only for tokenized transactions.\nYou can use this value on the receipt that you give to the cardholder.\n"},"prefix":{"type":"string","maxLength":6,"description":"The description for this field is not available."},"type":{"type":"string","maxLength":3,"description":"Type of card to authorize.\n- 001 Visa\n- 002 Mastercard\n- 003 Amex\n- 004 Discover\n"}}}}},"processingInformation":{"type":"object","properties":{"paymentSolution":{"type":"string","maxLength":12,"description":"Type of digital payment solution that is being used for the transaction. Possible Values:\n\n - **visacheckout**: Visa Checkout.\n - **001**: Apple Pay.\n - **005**: Masterpass. Required for Masterpass transactions on OmniPay Direct.\n - **006**: Android Pay.\n - **008**: Samsung Pay.\n"},"businessApplicationId":{"type":"string","description":"The description for this field is not available."}}},"processorInformation":{"type":"object","properties":{"processor":{"type":"object","properties":{"name":{"type":"string","maxLength":30,"description":"Name of the Processor.\n"}}}}},"pointOfSaleInformation":{"type":"object","properties":{"terminalId":{"type":"string","maxLength":8,"description":"Identifier for the terminal at your retail location. You can define this value yourself, but consult the\nprocessor for requirements.\n\nFor Payouts: This field is applicable for CtV.\n"},"terminalSerialNumber":{"type":"string","description":"The description for this field is not available."},"deviceId":{"type":"string","description":"The description for this field is not available."},"partner":{"type":"object","properties":{"originalTransactionId":{"type":"string","maxLength":50,"description":"Network transaction identifier (TID). You can use this value to identify a specific transaction when you are\ndiscussing the transaction with your processor. Not all processors provide this value.\n"}}}}},"riskInformation":{"type":"object","properties":{"providers":{"type":"object","properties":{"fingerprint":{"type":"object","properties":{"true_ipaddress":{"type":"string","maxLength":255,"description":"The description for this field is not available."},"hash":{"type":"string","maxLength":255,"description":"The description for this field is not available."},"smartId":{"type":"string","maxLength":255,"description":"The description for this field is not available."}}}}}}},"_links":{"type":"object","properties":{"transactionDetail":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}}}}}}},"_links":{"type":"object","properties":{"self":{"type":"object","properties":{"href":{"type":"string","description":"URL"},"method":{"type":"string","description":"HTTP method applied to above URL"}}}}}},"example":{"id":"87e1e4bd-cac2-49b1-919a-4d5e29a2e55d","save":"false","name":"Search By Code","timezone":"America/Chicago","query":"clientReferenceInformation.code:12345","offset":0,"limit":2000,"sort":"id:asc, submitTimeUtc:asc","count":22,"totalCount":22,"submitTimeUtc":"2018-09-18T16:59:28Z","_embedded":{"transactionSummaries":[{"id":"5217848115816817001541","submitTimeUtc":"2018-03-23T06:00:11Z","merchantId":"sandeep_wf","applicationInformation":{"status":"string","reasonCode":"string","rCode":"string","rFlag":"string","applications":[{"name":"ics_service_fee_calculate","status":"string","reasonCode":"string","rCode":"string","rFlag":"string","reconciliationId":"string","rMessage":"string","returnCode":"string"}]},"buyerInformation":{"merchantCustomerId":"123456"},"clientReferenceInformation":{"code":"12345","applicationName":"Service Fee Request","applicationUser":"sandeep_wf"},"consumerAuthenticationInformation":{"xid":"12345678","transactionId":"string"},"deviceInformation":{"ipAddress":"1.10.10.10"},"fraudMarkingInformation":{"reason":"fraud txn"},"merchantDefinedInformation":[{"key":"string","value":"string"}],"merchantInformation":{"resellerId":"wfbmcp"},"orderInformation":{"billTo":{"firstName":"Test","lastName":"TSS","email":"null@cybersource.com","country":"US","phoneNumber":"5120000000"},"shipTo":{"firstName":"Test","lastName":"TSS","address1":"201S.DivisionSt._1","country":"US","phoneNumber":"5120000000"},"amountDetails":{"totalAmount":"100.00","currency":"USD"}},"paymentInformation":{"paymentmethod":{"type":"credit card"},"customer":{"customerId":"12345"},"card":{"suffix":"1111","prefix":"123456","type":"credit card"}},"processingInformation":{"paymentSolution":"xyz","businessApplicationId":"string"},"processorInformation":{"processor":{"name":"FirstData"}},"pointOfSaleInformation":{"terminalId":"1","terminalSerialNumber":"123111123","deviceId":"asfaf12312313","partner":{"originalTransactionId":"131231414414"}},"riskInformation":{"providers":{"fingerprint":{"true_ipaddress":"1.101.102.112","hash":"tuWmt8Ubw0EAybBF3wrZcEqIcZsLr8YPldTQDUxAg2k=","smart_id":"23442fdadfa"}}},"_links":{"transactionDetail":{"href":"https://sl73paysvapq002.visa.com:2031/payment/tss/v2/transactions/5217848115816817001541","method":"GET"}}}]},"_links":{"self":{"href":"https://sl73paysvapq002.visa.com:2031/payment/tss/v2/searches/87e1e4bd-cac2-49b1-919a-4d5e29a2e55d","method":"GET"}}}}},"404":{"description":"The specified resource not found in the system."},"500":{"description":"Unexpected server error."}}}},"/ums/v1/users":{"get":{"summary":"Get user based on organization Id, username, permission and role","description":"This endpoint is to get all the user information depending on the filter criteria passed in the query.","tags":["UserManagement"],"operationId":"getUsers","parameters":[{"in":"query","name":"organizationId","type":"string","description":"This is the orgId of the organization which the user belongs to."},{"in":"query","name":"userName","type":"string","description":"User ID of the user you want to get details on."},{"in":"query","name":"permissionId","type":"string","description":"permission that you are trying to search user on."},{"in":"query","name":"roleId","type":"string","description":"role of the user you are trying to search on."}],"x-example":{"example0":{"summary":"User Management","value":[]}},"responses":{"200":{"description":"OK","schema":{"type":"object","title":"umsV1UsersGet200Response","properties":{"users":{"type":"array","items":{"type":"object","properties":{"accountInformation":{"type":"object","properties":{"userName":{"type":"string"},"roleId":{"type":"string"},"permissions":{"type":"array","items":{"type":"string","description":"array of permissions"}},"status":{"type":"string","enum":["active","inactive","locked","disabled","forgotpassword","deleted"]},"createdTime":{"type":"string","format":"date-time"},"lastAccessTime":{"type":"string","format":"date-time"},"languagePreference":{"type":"string"},"timezone":{"type":"string"}}},"organizationInformation":{"type":"object","properties":{"organizationId":{"type":"string"}}},"contactInformation":{"type":"object","properties":{"email":{"type":"string"},"phoneNumber":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"}}}}}}},"example":{"users":[{"accountInformation":{"userName":"auto_nonmember","roleId":"admin","permissions":["ReportViewPermission","ReportGeneratePermission"],"status":"active","createdTime":"2018-06-14T19:45:52.093Z","lastAccessTime":"2018-06-14T19:45:52.093Z","languagePreference":"en-US","timezone":"America/Los_Angeles"},"organizationInformation":{"organizationId":"auto_nonmember"},"contactInformation":{"email":"auto_nonmember@exchange.com","phoneNumber":"4445551234","firstName":"Zeta","lastName":"DMH"}}]}}},"400":{"description":"Invalid request.","schema":{"type":"object","title":"umsV1UsersGet400Response","properties":{"submitTimeUtc":{"type":"string","description":"Time of request in UTC. `Format: YYYY-MM-DDThh:mm:ssZ`\n\nExample 2016-08-11T22:47:57Z equals August 11, 2016, at 22:47:57 (10:47:57 p.m.). The T separates the date and the\ntime. The Z indicates UTC.\n"},"status":{"type":"string","description":"The status of the submitted transaction.","enum":["INVALID_REQUEST"]},"reason":{"type":"string","description":"The reason of the status.\n","enum":["MISSING_FIELD","INVALID_DATA","DUPLICATE_REQUEST","INVALID_CARD","INVALID_MERCHANT_CONFIGURATION","CAPTURE_ALREADY_VOIDED","ACCOUNT_NOT_ALLOWED_CREDIT"]},"message":{"type":"string","description":"The detail message related to the status and reason listed above."},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"This is the flattened JSON object field name/path that is either missing or invalid."},"reason":{"type":"string","description":"Possible reasons for the error.\n","enum":["MISSING_FIELD","INVALID_DATA"]}}}}}}},"500":{"description":"Unexpected server error."}}}}},"definitions":{"TokenizeResult":{"properties":{"keyId":{"type":"string","description":"The Key ID."},"token":{"type":"string","description":"The generated token. The token replaces card data and is used as the Subscription ID in the CyberSource Simple Order API or SCMP API."},"maskedPan":{"type":"string","description":"The masked card number displaying the first 6 digits and the last 4 digits."},"cardType":{"type":"string","description":"The card type."},"timestamp":{"type":"integer","format":"int64","description":"The UTC date and time in milliseconds at which the signature was generated."},"signedFields":{"type":"string","description":"Indicates which fields from the response make up the data that is used when verifying the response signature. See the [sample code] (https://github.com/CyberSource/cybersource-flex-samples/blob/master/java/spring-boot/src/main/java/com/cybersource/flex/application/CheckoutController.java) on how to verify the signature."},"signature":{"type":"string","description":"Flex-generated digital signature. To ensure the values have not been tampered with while passing through the client, verify this server-side using the public key generated from the /keys resource."},"discoverableServices":{"type":"object","additionalProperties":{"type":"object"}}}},"TokenizeParameters":{"type":"object","properties":{"keyId":{"type":"string","description":"Unique identifier for the generated token. This is obtained from the Generate Key request. See the [Java Script and Java examples] (http://apps.cybersource.com/library/documentation/dev_guides/Secure_Acceptance_Flex/Key/html) on how to import the key and encrypt using the imported key."},"cardInfo":{"type":"object","properties":{"cardNumber":{"type":"string","description":"Encrypted or plain text card number. If the encryption type of \u201cNone\u201d was used in the Generate Key request, this value can be set to the plaintext card number/Personal Account Number (PAN). If the encryption type of RsaOaep256 was used in the Generate Key request, this value needs to be the RSA OAEP 256 encrypted card number. The card number should be encrypted on the cardholders\u2019 device. The [WebCrypto API] (https://github.com/CyberSource/cybersource-flex-samples/blob/master/java/spring-boot/src/main/resources/public/flex.js) can be used with the JWK obtained in the Generate Key request."},"cardExpirationMonth":{"type":"string","description":"Two digit expiration month"},"cardExpirationYear":{"type":"string","description":"Four digit expiration year"},"cardType":{"type":"string","description":"Card Type. This field is required. Refer to the CyberSource Credit Card Services documentation for supported card types."}}}}},"KeyParameters":{"type":"object","properties":{"encryptionType":{"type":"string","description":"How the card number should be encrypted in the subsequent Tokenize Card request. Possible values are RsaOaep256 or None (if using this value the card number must be in plain text when included in the Tokenize Card request). The Tokenize Card request uses a secure connection (TLS 1.2+) regardless of what encryption type is specified."}}},"JsonWebKey":{"type":"object","description":"The public key in JSON Web Key (JWK) format. This format is useful for client side encryption in JavaScript based implementations.","properties":{"kty":{"type":"string","description":"Algorithm used to encrypt the public key."},"use":{"type":"string","description":"Defines whether to use the key for encryption (enc) or verifying a signature (sig). Always returned as enc."},"kid":{"type":"string","description":"The key ID in JWK format."},"n":{"type":"string","description":"JWK RSA Modulus"},"e":{"type":"string","description":"JWK RSA Exponent"}}},"DerPublicKey":{"type":"object","description":"The public key in DER format. Used to validate the response from the Tokenize Card request. Additionally this format is useful for client side encryption in Android and iOS implementations.","properties":{"format":{"type":"string","description":"Specifies the format of the public key; currently X.509."},"algorithm":{"type":"string","description":"Algorithm used to encrypt the public key."},"publicKey":{"type":"string","description":"Base64 encoded public key value."}}},"KeyResult":{"properties":{"keyId":{"type":"string","description":"Unique identifier for the generated token. Used in the subsequent Tokenize Card request from your customer\u2019s device or browser."},"der":{"type":"object","description":"The public key in DER format. Used to validate the response from the Tokenize Card request. Additionally this format is useful for client side encryption in Android and iOS implementations.","properties":{"format":{"type":"string","description":"Specifies the format of the public key; currently X.509."},"algorithm":{"type":"string","description":"Algorithm used to encrypt the public key."},"publicKey":{"type":"string","description":"Base64 encoded public key value."}}},"jwk":{"type":"object","description":"The public key in JSON Web Key (JWK) format. This format is useful for client side encryption in JavaScript based implementations.","properties":{"kty":{"type":"string","description":"Algorithm used to encrypt the public key."},"use":{"type":"string","description":"Defines whether to use the key for encryption (enc) or verifying a signature (sig). Always returned as enc."},"kid":{"type":"string","description":"The key ID in JWK format."},"n":{"type":"string","description":"JWK RSA Modulus"},"e":{"type":"string","description":"JWK RSA Exponent"}}}}},"CardInfo":{"type":"object","properties":{"cardNumber":{"type":"string","description":"Encrypted or plain text card number. If the encryption type of \u201cNone\u201d was used in the Generate Key request, this value can be set to the plaintext card number/Personal Account Number (PAN). If the encryption type of RsaOaep256 was used in the Generate Key request, this value needs to be the RSA OAEP 256 encrypted card number. The card number should be encrypted on the cardholders\u2019 device. The [WebCrypto API] (https://github.com/CyberSource/cybersource-flex-samples/blob/master/java/spring-boot/src/main/resources/public/flex.js) can be used with the JWK obtained in the Generate Key request."},"cardExpirationMonth":{"type":"string","description":"Two digit expiration month"},"cardExpirationYear":{"type":"string","description":"Four digit expiration year"},"cardType":{"type":"string","description":"Card Type. This field is required. Refer to the CyberSource Credit Card Services documentation for supported card types."}}},"Error":{"properties":{"responseStatus":{"properties":{"status":{"type":"number","description":"HTTP Status code."},"reason":{"type":"string","description":"Error Reason Code."},"message":{"type":"string","description":"Error Message."},"correlationId":{"type":"string","description":"API correlation ID."},"details":{"type":"array","items":{"properties":{"location":{"type":"string","description":"Field name referred to for validation issues."},"message":{"type":"string","description":"Description or code of any error response."}}}}}},"_links":{"properties":{"self":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}},"documentation":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"next":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}}}}}},"Link":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}},"Links":{"properties":{"self":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}},"documentation":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"next":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}}}},"ResponseStatus":{"properties":{"status":{"type":"number","description":"HTTP Status code."},"reason":{"type":"string","description":"Error Reason Code."},"message":{"type":"string","description":"Error Message."},"correlationId":{"type":"string","description":"API correlation ID."},"details":{"type":"array","items":{"properties":{"location":{"type":"string","description":"Field name referred to for validation issues."},"message":{"type":"string","description":"Description or code of any error response."}}}}}},"ResponseStatusDetails":{"properties":{"location":{"type":"string","description":"Field name referred to for validation issues."},"message":{"type":"string","description":"Description or code of any error response."}}},"ErrorResponse":{"type":"object","properties":{"responseStatus":{"properties":{"status":{"type":"number","description":"HTTP Status code."},"reason":{"type":"string","description":"Error Reason Code."},"message":{"type":"string","description":"Error Message."},"correlationId":{"type":"string","description":"API correlation ID."},"details":{"type":"array","items":{"properties":{"location":{"type":"string","description":"Field name referred to for validation issues."},"message":{"type":"string","description":"Description or code of any error response."}}}}}},"_links":{"type":"object","properties":{"next":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"documentation":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"self":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}}}}},"ErrorLinks":{"type":"object","properties":{"next":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"documentation":{"type":"array","items":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}},"self":{"properties":{"href":{"type":"string","description":"URI of the linked resource."},"title":{"type":"string","description":"Label of the linked resource."},"method":{"type":"string","description":"HTTP method of the linked resource."}}}}}}} \ No newline at end of file diff --git a/generator/cybersource_java_sdk_gen.bat b/generator/cybersource_java_sdk_gen.bat new file mode 100644 index 000000000..4553e050f --- /dev/null +++ b/generator/cybersource_java_sdk_gen.bat @@ -0,0 +1,8 @@ +mkdir %~dp0JavaFile +cd %~dp0 +java -jar swagger-codegen-cli-2.2.3.jar generate -t cybersource-java-template\libraries\okhttp-gson -i cybersource-rest-spec.json -l java -o JavaFile -c %~dp0cybersource-java-config.json + +pause + + +