MENU
Pdcflowlogo
PHP CSharp Perl Ruby

Introduction

Welcome to the PDCflow API Docs! Here you can find information and examples on the diverse selection of APIs used to integrate with PDCflow.

Attribute Tables

Attribute tables include all of the critical information that you will use to integrate with our APIs. The example below shows you where to find each piece of information for an Attribute.

Attribute Description
Attribute Name
FormatMax Length
If Required/Conditional
This is where there will be a description of the Attribute and what it is used for.
Format: formatted-sample
Constraint(s): Explanation of constraint(s)
Valid value(s): value1, value2
Default: The Default Value

Code Samples

wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
// Libraries needed. On an Ubuntu system, run the following commands:

sudo apt-get install php7.0-soap
sudo apt-get install php-curl
sudo apt-get install php-json

Debugging SOAP in PHP:
Add tracing:
<?php $client = new SoapClient($url, array('trace' => 1)); ?>

Output the results of the trace:
<?php var_dump( $client->__getLastRequest() ); ?>

Debugging REST in PHP:
<?php curl_setopt($curl, CURLOPT_VERBOSE, true); ?>
# Libraries needed. On an Ubuntu system, run the following commands:

sudo apt-get install cpanminus
sudo cpan App::cpanminus (take defaults)
sudo cpanm LWP::Authen::Wsse
sudo cpanm SOAP::Lite
# Libraries needed. On an Ubuntu system, run the following commands:

sudo apt-get install ruby-dev
sudo apt-get install zlib1g-dev
sudo gem install savon
sudo gem install curl
sudo apt-get install libcurl4-gnutls-dev
sudo gem install curb

You can view sample code in the dark area to the right. We provide examples in PHP, Perl, & Ruby. For the code samples to work, each language will require the installation of specific libraries which are listed to the right.

Integrator Forum

If you can’t find the information you are looking for, need an example not provided here, or have a specific question you want answered head over to our API Forum.

Company Administration Service

The Company Administration Service allows easy integration for creating, modifying, and retrieving of Companies, Locations and Groups, and their related Settings. Requests are made through POST, PUT, PATCH, GET or DELETE requests.

Authentication for the CompanyAdministrationService will be done with a Base64 encoded username:password, passed in through the BASIC HTTP Authorization Header.
Any endpoints under /companies are accessible to get or modify even if the company is INACTIVE.
Any endpoints under /locations or groups can only be retrieved, modified or created for an ACTIVE company.

General Service Notes

Credit Card API [DEPRECATED]

The credit card API allows you to easily process credit cards, tokenize a card number for future use, and run payments exclusively from a tokenized card.

API Request

userInfo

The following table describes the individual elements of the userInfo object.

Attribute Description
customerID
Numeric4
Required
A four digit customer ID that together with the securityKey uniquely identifies the customer processing credit cards.
securityKey
Alphanumeric128
Required
A password that together with the customerId uniquely identifies the customer processing credit cards.
accountSet
Numeric4
Required
Code to determine what account to deposit funds.
Format: Always 4 digits (0001, 0012, 0104, etc)
testMode
Deprecated
This element is deprecated. Do not include in request.
userName
Alphanumeric75
The user who submitted the transaction.

creditCard

The following table describes the individual elements of the creditCard object.

Attribute Description
cardHolderFirstName
Alpha45
Required
First name of card holder.
cardHolderLastName
Alpha45
Required
Last name of card holder.
cardHolderStreetAddress1
Alphanumeric80
Card holder street address line 1.
cardHolderStreetAddress2
Alphanumeric45
Card holder street address line 2.
cardHolderCity
Alphanumeric45
Card holder city.
cardHolderState
Alpha2
Card holder state.
Format: two character abbreviation (UT, CA, MI, etc)
cardHolderZipCode
Alpha10
Card holder zip code.
cardHolderCountry
Deprecated
This element is deprecated. Do not include in request.
cardHolderEmailAddress
Alphanumeric75
Email address where a receipt will be sent at the completion of the transaction.
cardHolderPhoneNumber
Alphanumeric12
Card holder telephone number.
Format: XXX-XXX-XXXX
cardHolderPhoneNumberType
Deprecated
This element is deprecated. Do not include in request.
accountReference
Alphanumeric45
Required
Reference/ID value. This is often the customer account number from your system.
memoInformation
Alphanumeric50
Memo information for the explanation of the transaction.
cardMagStripeData
AlphanumericN/A
Conditional
Mag Stripe data read from card using a PDCFlow approved card scanner.
Constraint(s): Required when using scanner.
cardNumber
Alphanumeric16
Conditional
Credit card number.
Constraint(s): Required for all transactions, except for CREDIT or VOID that were originally scanned through an approved PDCFlow scanner.

See Test Credit Cards in the Appendix for values and expected results.
cardExpirationMonth
Numeric2
Conditional
Credit expiration month.
Format: 2 digit month, such as 01, 08, 12, etc.
Constraint(s): Required for all transactions, except for CREDIT or VOID that were originally scanned through an approved PDCFlow scanner.
cardExpirationYear
Numeric2
Conditional
Card expiration year.
Format: 2 digit year, such as 17.
Constraint(s): Required for all transactions, except for CREDIT or VOID that were originally scanned through an approved PDCFlow scanner.
cardCvv2
Numeric4
Card CVV2 number. This will be 3 digits for Visa, MasterCard, and Discover, and 4 digits for American Express cards.
chargeAmount
Numeric11
Conditional
The net dollar amount paid by the payer.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc.
Constraint(s): Required for all transactions, except when storing a card using the storeCard method.
convenienceFee
Numeric11
Conditional
Transaction fee amount. Fee amount to be added to the charge amount. If no fee is to be added to this transaction a value of zero (0) still needs to be provided.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc.
Constraint(s): Required for all transactions, except when storing a card using the storeCard method.
currencyType
Alpha3
Required
As an integrator, this must be set to EXT.
Valid value(s): EXT
processingCommand
Alpha6
Required
Indicates how the card is to be processed.
Valid value(s): SALE, VOID, CREDIT
secondaryTrace
Alphanumeric50
Location information about a company.
originalOrderNumber
Numeric20
Conditional
When issuing a CREDIT or VOID, the original order number should be provided here.
Constraint(s): Required with processingCommand of CREDIT or VOID.
originalAmount
Deprecated
This element is deprecated. Do not include in request.

vaultInfo

The following table describes the individual elements of the vaultInfo object.

Attribute Description
vaultKey
Alphanumeric20
Conditional
The token for a card. This token should have been previously stored. Passing in this token will only automatically populate the card number and the card expiration date for processing.
Constraint(s): Required when using the processStoredCreditCardTransaction method.

API Result

-- Sample success XML --
<return>
    <processingResult>&lt;processing-results>&lt;result>OK&lt;/result>&lt;/processing-results></processingResult>
    <gatewayResponseData><![CDATA[<?xml version="1.0" ?><com.pdc4u.webservices.gps.TransactionResponse><requestResultStatus>APPROVED</requestResultStatus><cardTransactionResult><transactionId>23608</transactionId><cardToken>removedFromSample</cardToken><authorizationCode>095242</authorizationCode><cvv2ResultCode>M</cvv2ResultCode><roundTripNVPS></roundTripNVPS></cardTransactionResult><checkTransactionResult></checkTransactionResult><checkStatusUpdateResult><newStatus></newStatus><transactionId></transactionId><roundTripNVPS></roundTripNVPS></checkStatusUpdateResult><requestErrors><requestError></requestError></requestErrors></com.pdc4u.webservices.gps.TransactionResponse>]]></gatewayResponseData>
    <orderNumber>23608</orderNumber>
    <authorizationCode>095242</authorizationCode>
    <softwareVersion/>
    <state>OK</state>
 </return>
 -- Sample error XML --
 <return>
     <processingResult><![CDATA[<processing-results><result>Error</result><error>Field Card Expiration Year is required.</error><error>Field Card Expiration Month is required.</error></processing-results>]]></processingResult>
     <gatewayResponseData><![CDATA[<?xml version="1.0" ?><com.pdc4u.webservices.gps.TransactionResponse><requestResultStatus>ERROR</requestResultStatus><cardTransactionResult><transactionId></transactionId><authorizationCode></authorizationCode><cvv2ResultCode></cvv2ResultCode><roundTripNVPS></roundTripNVPS></cardTransactionResult><checkTransactionResult><roundTripNVPS></roundTripNVPS></checkTransactionResult><checkStatusUpdateResult><newStatus></newStatus><transactionId></transactionId><roundTripNVPS></roundTripNVPS></checkStatusUpdateResult><requestErrors><requestError><com.pdc4u.webservices.gps.RequestError><code>10001</code><description>Field Card Expiration Year is required.</description></com.pdc4u.webservices.gps.RequestError><com.pdc4u.webservices.gps.RequestError><code>10001</code><description>Field Card Expiration Month is required.</description></com.pdc4u.webservices.gps.RequestError></requestError></requestErrors></com.pdc4u.webservices.gps.TransactionResponse>]]></gatewayResponseData>
     <orderNumber/>
     <authorizationCode/>     
     <softwareVersion/>
     <state>ERROR</state>
     <transactionProcessingMessages>
        <message>Field Card Expiration Year is required.</message>
        <xmlTag>error</xmlTag>
     </transactionProcessingMessages>
     <transactionProcessingMessages>
        <message>Field Card Expiration Month is required.</message>
        <xmlTag>error</xmlTag>
     </transactionProcessingMessages>
  </return>

The following table describes the individual elements in a response. Sample success and failure examples are listed to the right.

Attribute Description
processingResult
XMLN/A
Result of the transaction.
gatewayResponseData
XMLN/A
Similar to processingResult, but contains additional information, such as a card token, cvv2 result, and customizable round-trip name/value pairs.
orderNumber
Numeric20
Order/Confirmation number of transaction. Returned in conjunction with authorizationCode when a transaction is successfully processed through the gateway.
authorizationCode
Alphanumeric75
Returned in conjunction with orderNumber when a transaction is successfully processed through the gateway. This value will be blank when issuing a VOID.
softwareVersion
Alphanumeric20
The version number of the the CreditCard SOAP Service.
state
Alpha10
The result of a request. A successful request will have a state of OK. Attribute not present when using storeCard.
transactionProcessingMessages
XMLN/A
Error messages from a request. This attribute will not be present on a successful request, but can exist one or more times with an error. See example to the right for structure of attribute.

API Fault

Generally, the only time a fault should be thrown is if you can’t connect to our system, or if the soap package is malformed. Verify you can access our WSDL and that all required elements listed above are present in your request.

Credit Card Vault

PDCFlow also offers a Credit Card Vault for even more secure credit card processing, particularly in the event of a recurring payment or other multiple transactions. The Vault is fully PCI-DSS compliant and allows you to process transactions without the risk of passing actual credit card information in a live environment. There are two distinct web services in the package. The first is to set up the key that will apply to the credit card number and then a second service to process a transaction based on the key.

The WSDL for the Vault and the Credit Card Processing are nearly identical. It will require the same core input as listed in the previous chart for the Credit Card transaction WSDL. The primary difference is that you will “Store” the card number in the Vault and the Vault will do any future processing of that card. When you store the card in the Vault, it will return a “cardStorageResult” as opposed to a card processing result. This element will also return a unique “authorizationKey”. You will need to save and store this key. When you wish to process a charge to the credit card, you will use the Key as a reference for the card number that is inside the Vault.

A stored card transaction uses the same basic information as for a normal credit card transaction. For the new charge, you will need to send the new transaction information that includes the processingCommand and the chargeAmount/convenienceFee.

Sample Code

This section offers some client implementation examples in different languages. Keep in mind, these are only minimalistic examples used to demonstrate the Credit Card Services API and are not meant for production use.

Process a basic credit card transaction

<?php

// Get customer-specific information
$userInformation = [
    'accountSet' => '0001',
    'customerID' => '0000',
    'securityKey' => 'SomeSecurityKey',
    'userName' => 'frontenduser@pdc4u.com'
];

// Payment-specific information
$creditCardInformation = [
    'cardHolderFirstName' => 'Adam',
    'cardHolderLastName' => 'Test',
    'cardHolderStreetAddress1' => '1234 Main St.',
    'cardHolderStreetAddress2' => 'Apt. 7B',
    'cardHolderCity' => 'Ogden',
    'cardHolderState' => 'UT',
    'cardHolderZipCode' => '84404',
    'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
    'cardHolderPhoneNumber' => '777-777-7777',
    'accountReference' => 'AB1234',
    'memoInformation' => 'December payment',
    'cardMagStripeData' => '',
    'cardNumber' => '4000100011112224',
    'cardExpirationMonth' => '09',
    'cardExpirationYear'=> '22',
    'cardCvv2' => '123',        
    'chargeAmount' => '5.00',
    'convenienceFee' => '0.50',
    'currencyType' => 'EXT',
    'processingCommand' => 'SALE',
    'secondaryTrace' => '',
    'originalOrderNumber' => ''
];

$url = 'https://cclegacydemo.pdc4u.com/CreditCardServices/CreditCardTransactionProcessor?wsdl';
$namespace = 'http://transaction.webservices.pdc4u.com';
$method = 'processCreditCardTransaction';
$params = [
    'creditCard' => $creditCardInformation,
    'userInfo'=> $userInformation
];

$client = new SoapClient($url);

try {
  $response = $client->__soapCall(
    $method,
    [$params, $namespace]
  );

  print_r($response);
}
catch (SoapFault $fault) {
  print_r($fault);
}

#!/usr/bin/perl

use SOAP::Lite +trace => 'debug';

my $soap = SOAP::Lite
   ->readable(1)
   ->autotype(0)
   ->ns( 'http://transaction.webservices.pdc4u.com/', "ns1" )
   ->proxy( 'https://cclegacydemo.pdc4u.com/CreditCardServices/CreditCardTransactionProcessor?wsdl' );

my %userInformation = (
  'pdcAccountSet' => '01',
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'userName' => 'frontenduser@pdc4u.com'
);

# Payment-specific information
my %creditCardInformation = (
   'cardHolderFirstName' => 'Adam',
   'cardHolderLastName' => 'Test',
   'cardHolderStreetAddress1' => '1234 Main St.',
   'cardHolderStreetAddress2' => 'Apt. 7B',
   'cardHolderCity' => 'Ogden',
   'cardHolderState' => 'UT',
   'cardHolderZipCode' => '84404',
   'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
   'cardHolderPhoneNumber' => '777-777-7777',
   'accountReference' => 'AB1234',
   'memoInformation' => 'December payment',
   'cardMagStripeData' => '',
   'cardNumber' => '4000100011112224',
   'cardExpirationMonth' => '09',
   'cardExpirationYear'=> '22',
   'cardCvv2' => '123',
   'chargeAmount' => '5.00',
   'convenienceFee' => '0.50',
   'currencyType' => 'EXT',
   'processingCommand' => 'SALE',
   'secondaryTrace' => '',
   'originalOrderNumber' => ''
);

print $soap->call( 'processCreditCardTransaction',
   SOAP::Data->name('creditCard' => \%creditCardInformation),
   SOAP::Data->name('userInfo' => \%userInformation)
)->result;
#!/usr/bin/ruby

require 'savon' # version 2.0

begin
   # create a client for the service
   client = Savon.client(wsdl: 'https://cclegacydemo.pdc4u.com/CreditCardServices/CreditCardTransactionProcessor?wsdl',
      log_level: :debug,
      log: true,
      pretty_print_xml: true)

   puts "Available operations: "
   client.operations.each { |x| puts "   #{x}", "\n" } # find which operations are supported

   # Get customer-specific information
   userInformation = {
      'accountSet' => '0001',
      'customerID' => '0000',
      'securityKey' => 'SomeSecurityKey',
      'userName' => 'frontenduser@pdc4u.com'
   }

   # Payment-specific information
   creditCardInformation = {
      'cardHolderFirstName' => 'Adam',
      'cardHolderLastName' => 'Test',
      'cardHolderStreetAddress1' => '1234 Main St.',
      'cardHolderStreetAddress2' => 'Apt. 7B',
      'cardHolderCity' => 'Ogden',
      'cardHolderState' => 'UT',
      'cardHolderZipCode' => '84404',
      'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
      'cardHolderPhoneNumber' => '777-777-7777',
      'accountReference' => 'AB1234',
      'memoInformation' => 'December payment',
      'cardMagStripeData' => '',
      'cardNumber' => '4000100011112224',
      'cardExpirationMonth' => '09',
      'cardExpirationYear'=> '22',
      'cardCvv2' => '123',
      'chargeAmount' => '5.00',
      'convenienceFee' => '0.50',
      'currencyType' => 'EXT',
      'processingCommand' => 'SALE',
      'secondaryTrace' => '',
      'originalOrderNumber' => ''
   }

   params = {
      'creditCard' => creditCardInformation,
      'userInfo'=> userInformation
   }

   response = client.call(:process_credit_card_transaction, message: params)

   puts response
rescue
   puts "Caught: #$!\n"
end

General transactions will use this method. It will simply accept credit card details, and process the card.

The URL to process a credit card is:
test wsdl:
https://cclegacydemo.pdc4u.com/CreditCardServices/CreditCardTransactionProcessor?wsdl
live wsdl:
https://cclegacy.pdc4u.com/CreditCardServices/CreditCardTransactionProcessor?wsdl

The namespace to use is:
http://transaction.webservices.pdc4u.com

The method to use is:
processCreditCardTransaction

Store a credit card in the vault

<?php

// Get customer-specific information
$userInformation = [
    'accountSet' => '0001',
    'customerID' => '0000',
    'securityKey' => 'SomeSecurityKey',
    'userName' => 'frontenduser@pdc4u.com'
];

// Payment-specific information
$creditCardInformation= [
    'cardHolderFirstName' => 'Adam',
    'cardHolderLastName' => 'Test',
    'cardHolderStreetAddress1' => '1234 Main St.',
    'cardHolderStreetAddress2' => 'Apt. 7B',
    'cardHolderCity' => 'Ogden',
    'cardHolderState' => 'UT',
    'cardHolderZipCode' => '84404',
    'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
    'cardHolderPhoneNumber' => '777-777-7777',
    'accountReference' => 'AB1234',
    'memoInformation' => 'December payment',
    'cardMagStripeData' => '',
    'cardNumber' => '4000100011112224',
    'cardExpirationMonth' => '09',
    'cardExpirationYear'=> '22',
    'cardCvv2' => '',       
    'chargeAmount' => '',
    'convenienceFee' => '',
    'currencyType' => 'EXT',
    'processingCommand' => 'SALE',
    'secondaryTrace' => '',
    'originalOrderNumber' => ''
];

$url = 'https://cclegacydemo.pdc4u.com/CreditCardServices/CardVault?wsdl';
$namespace = 'http://transaction.webservices.pdc4u.com';
$method = 'storeCard';
$params = [
    'creditCard' => $creditCardInformation,
    'userInfo'=> $userInformation
];

$client = new SoapClient($url);

try {
  $response = $client->__soapCall(
    $method,
    [$parms, $namespace]
  );

  print_r($response);
}
catch (SoapFault $fault) {
  print_r($fault);
}
#!/usr/bin/perl

use SOAP::Lite +trace => 'debug';

my $soap = SOAP::Lite
   ->readable(1)
   ->autotype(0)
   ->ns( 'http://transaction.webservices.pdc4u.com/', "ns1" )
   ->proxy( 'https://cclegacydemo.pdc4u.com/CreditCardServices/CardVault?wsdl' );

my %userInformation = (
  'pdcAccountSet' => '01',
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'userName' => 'frontenduser@pdc4u.com'
);

# Payment-specific information
my %creditCardInformation = (
   'cardHolderFirstName' => 'Adam',
   'cardHolderLastName' => 'Test',
   'cardHolderStreetAddress1' => '1234 Main St.',
   'cardHolderStreetAddress2' => 'Apt. 7B',
   'cardHolderCity' => 'Ogden',
   'cardHolderState' => 'UT',
   'cardHolderZipCode' => '84404',
   'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
   'cardHolderPhoneNumber' => '777-777-7777',
   'accountReference' => 'AB1234',
   'memoInformation' => 'December payment',
   'cardMagStripeData' => '',
   'cardNumber' => '4000100011112224',
   'cardExpirationMonth' => '09',
   'cardExpirationYear'=> '22',
   'cardCvv2' => '123',
   'chargeAmount' => '',
   'convenienceFee' => '',
   'currencyType' => 'EXT',
   'processingCommand' => 'SALE',
   'secondaryTrace' => '',
   'originalOrderNumber' => ''
);

print $soap->call( 'storeCard',
   SOAP::Data->name('creditCard' => \%creditCardInformation),
   SOAP::Data->name('userInfo' => \%userInformation)
)->result;
#!/usr/bin/ruby

require 'savon' # version 2.0

begin
   # create a client for the service
   client = Savon.client(wsdl: 'https://cclegacydemo.pdc4u.com/CreditCardServices/CardVault?wsdl',
      log_level: :debug,
      log: true,
      pretty_print_xml: true)

   puts "Available operations: "
   client.operations.each { |x| puts "   #{x}", "\n" } # find which operations are supported

   # Get customer-specific information
   userInformation = {
      'accountSet' => '0001',
      #'customerID' => '0000',
      #'securityKey' => 'SomeSecurityKey',
      'customerID' => '6299',
      'securityKey' => '31819d62fe0161d307defb1737b74ba4',
      'userName' => 'frontenduser@pdc4u.com'
   }

   # Payment-specific information
   creditCardInformation= {
      'cardHolderFirstName' => 'Adam',
      'cardHolderLastName' => 'Test',
      'cardHolderStreetAddress1' => '1234 Main St.',
      'cardHolderStreetAddress2' => 'Apt. 7B',
      'cardHolderCity' => 'Ogden',
      'cardHolderState' => 'UT',
      'cardHolderZipCode' => '84404',
      'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
      'cardHolderPhoneNumber' => '777-777-7777',
      'accountReference' => 'AB1234',
      'memoInformation' => 'December payment',
      'cardMagStripeData' => '',
      'cardNumber' => '4000100011112224',
      'cardExpirationMonth' => '09',
      'cardExpirationYear'=> '22',
      'cardCvv2' => '',
      'chargeAmount' => '',
      'convenienceFee' => '',
      'currencyType' => 'EXT',
      'processingCommand' => 'SALE',
      'secondaryTrace' => '',
      'originalOrderNumber' => ''
   }

   params = {
      'creditCard' => creditCardInformation,
      'userInfo'=> userInformation
   }

   response = client.call(:store_card, message: params)

   puts response
rescue
   puts "Caught: #$!\n"
end

Tokenize card details (card number, card expiration month, card expiration year) to be used later, generally in conjunction with the next code sample, the processStoredCreditCardTransaction method. This will only store a card, it will not process a transaction. Transaction details are generally not required at this point, as you are only storing card information. The cvv2 is also not necessary, as this piece of data can not be stored.

The URL to test the vault storage service is:
test wsdl:
https://cclegacydemo.pdc4u.com/CreditCardServices/CardVault?wsdl
live wsdl:
https://cclegacy.pdc4u.com/CreditCardServices/CardVault?wsdl

The namespace to use is:
http://transaction.webservices.pdc4u.com

The method to use is:
storeCard

Process a credit card transaction from the vault

<?php

// Get customer-specific information
$userInformation = [
    'accountSet' => '0001',
    'customerID' => '0000',
    'securityKey' => 'SomeSecurityKey',
    'userName' => 'frontenduser@pdc4u.com'
];

// Payment-specific information
$creditCardInformation = [
    'cardHolderFirstName' => 'Adam',
    'cardHolderLastName' => 'Test',
    'cardHolderStreetAddress1' => '1234 Main St.',
    'cardHolderStreetAddress2' => 'Apt. 7B',
    'cardHolderCity' => 'Ogden',
    'cardHolderState' => 'UT',
    'cardHolderZipCode' => '84404',
    'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
    'cardHolderPhoneNumber' => '777-777-7777',
    'accountReference' => 'AB1234',
    'memoInformation' => 'December payment',
    'cardMagStripeData' => '',
    'cardNumber' => '',
    'cardExpirationMonth' => '',
    'cardExpirationYear'=> '',
    'cardCvv2' => '',       
    'chargeAmount' => '5.00',
    'convenienceFee' => '0.50',
    'currencyType' => 'EXT',
    'processingCommand' => 'SALE',
    'secondaryTrace' => '',
    'originalOrderNumber' => ''
];

//Tokenized card from vault to use
$vaultInformation = [
    'vaultKey' => 'abc123'
];

$url = 'https://cclegacydemo.pdc4u.com/CreditCardServices/StoredCreditCardTransactionProcessor?wsdl';
$namespace = 'http://transaction.webservices.pdc4u.com';
$method = 'processStoredCreditCardTransaction';
$params = [
    'creditCard' => $creditCardInformation,
    'userInfo'=> $userInformation,
    'vaultInfo' => $vaultInformation
];

$client = new SoapClient($url);

try {
  $response = $client->__soapCall(
    $method,
    [$parms, $namespace]
  );

  print_r($response);
}
catch (SoapFault $fault) {
  print_r($fault);
}
#!/usr/bin/perl

use SOAP::Lite +trace => 'debug';

my $soap = SOAP::Lite
   ->readable(1)
   ->autotype(0)
   ->ns( 'http://transaction.webservices.pdc4u.com/', "ns1" )
   ->proxy( 'https://cclegacydemo.pdc4u.com/CreditCardServices/StoredCreditCardTransactionProcessor?wsdl' );

my %userInformation = (
  'pdcAccountSet' => '01',
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'userName' => 'frontenduser@pdc4u.com'
);

# Payment-specific information
my %creditCardInformation = (
   'cardHolderFirstName' => 'Adam',
   'cardHolderLastName' => 'Test',
   'cardHolderStreetAddress1' => '1234 Main St.',
   'cardHolderStreetAddress2' => 'Apt. 7B',
   'cardHolderCity' => 'Ogden',
   'cardHolderState' => 'UT',
   'cardHolderZipCode' => '84404',
   'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
   'cardHolderPhoneNumber' => '777-777-7777',
   'accountReference' => 'AB1234',
   'memoInformation' => 'December payment',
   'cardMagStripeData' => '',
   'cardNumber' => '',
   'cardExpirationMonth' => '',
   'cardExpirationYear'=> '',
   'cardCvv2' => '',
   'chargeAmount' => '5.00',
   'convenienceFee' => '0.50',
   'currencyType' => 'EXT',
   'processingCommand' => 'SALE',
   'secondaryTrace' => '',
   'originalOrderNumber' => ''
);

# Tokenized card from vault to use
my %vaultInformation = (
   'vaultKey' => 'abc123'
);

print $soap->call( 'processStoredCreditCardTransaction',
   SOAP::Data->name('creditCard' => \%creditCardInformation),
   SOAP::Data->name('userInfo' => \%userInformation),
   SOAP::Data->name('vaultInfo' => \%vaultInformation)
)->result;
#!/usr/bin/ruby

require 'savon' # version 2.0

begin
   # create a client for the service
   client = Savon.client(wsdl: 'https://cclegacydemo.pdc4u.com/CreditCardServices/StoredCreditCardTransactionProcessor?wsdl',
      log_level: :debug,
      log: true,
      pretty_print_xml: true)

   puts "Available operations: "
   client.operations.each { |x| puts "   #{x}", "\n" } # find which operations are supported

   # Get customer-specific information
   userInformation = {
      'accountSet' => '0001',
      'customerID' => '0000',
      'securityKey' => 'SomeSecurityKey',
      'userName' => 'frontenduser@pdc4u.com'
   };

   # Payment-specific information
   creditCardInformation = {
      'cardHolderFirstName' => 'Adam',
      'cardHolderLastName' => 'Test',
      'cardHolderStreetAddress1' => '1234 Main St.',
      'cardHolderStreetAddress2' => 'Apt. 7B',
      'cardHolderCity' => 'Ogden',
      'cardHolderState' => 'UT',
      'cardHolderZipCode' => '84404',
      'cardHolderEmailAddress' => 'adamemail@pdc4u.com',
      'cardHolderPhoneNumber' => '777-777-7777',
      'accountReference' => 'AB1234',
      'memoInformation' => 'December payment',
      'cardMagStripeData' => '',
      'cardNumber' => '',
      'cardExpirationMonth' => '',
      'cardExpirationYear'=> '',
      'cardCvv2' => '',
      'chargeAmount' => '5.00',
      'convenienceFee' => '0.50',
      'currencyType' => 'EXT',
      'processingCommand' => 'SALE',
      'secondaryTrace' => '',
      'originalOrderNumber' => ''
   }

   # Tokenized card from vault to use
   vaultInformation = {
      'vaultKey' => 'abc123'
   }

   params = {
      'creditCard' => creditCardInformation,
      'userInfo'=> userInformation,
      'vaultInfo' => vaultInformation
   }

   response = client.call(:process_stored_credit_card_transaction, message: params)

   puts response
rescue
   puts "Caught: #$!\n"
end

A vault key should have been stored previously. Generally, you would use the previous code example to generate the vault key (storeCard method). Using that key, you can now process a card without having to resubmit the card information. A tokenized card will only auto-populate the card number and the card expiration date. No other previous transaction information will be used in this transaction.

The URL for testing the processing on a card that is already in the vault is:
test wsdl:
https://cclegacydemo.pdc4u.com/CreditCardServices/StoredCreditCardTransactionProcessor?wsdl
live wsdl:
https://cclegacy.pdc4u.com/CreditCardServices/StoredCreditCardTransactionProcessor?wsdl

The namespace to use is:
http://transaction.webservices.pdc4u.com

The method to use is:
processStoredCreditCardTransaction

ECheck API [DEPRECATED]

This document describes the different objects and methods required to use the PDCFlow ECheckServices SOAP services.

The PDCFlow ECheck API consists of a few web services:

Transaction Processing

Submit an ACH transaction to the PDCFlow ACH system. A transaction can be processed one at a time, or in a batch mode. The objects required are the same. See the sample code below for how to send one transaction vs multiple transactions.

API Processing Request

userInfo

The following table describes the individual elements of the userInfo object.

Attribute Description
customerID
Numeric4
Required
A four digit customer ID that together with the securityKey uniquely identifies the customer processing ACH transactions.
securityKey
Alphanumeric128
Required
A password that together with the customerID uniquely identifies the customer processing ACH transactions.
pdcAccountSet
Numeric2
Required
Code to determine what account to deposit funds.
Format: 01, 02, 10, etc.
userName
Alphanumeric50
The user who submitted the transaction.
groupID
Deprecated
This element is deprecated. Do not include in request.
interLevelBillingCode
Deprecated
This element is deprecated. Do not include in request.

API Processing Request

achTransaction

The following table describes the individual elements of the achTransaction object.

Attribute Description
payorFirstName
Alpha45
Required
Payor first name.
payorLastName
Alpha45
Required
Payor last name.
payorStreetAddress1
Alphanumeric45
The first line of the street/mailing address of the payor.
payorStreetAddress2
Alphanumeric45
The second line of the street/mailing address of the payor.
payorCity
Alpha45
Payor city.
payorState
Alphanumeric2
Payor state.
Format: two character abbreviation (UT, CA, MI, etc)
payorZip
Numeric10
Payor zip code.
transactionEmailAddress
Alphanumeric75
Email address where a receipt will be sent at the completion of the transaction.
payorPhoneNumber
Numeric15
Payor telephone number.
Format: XXX-XXX-XXXX
payorPhoneNumberType
Deprecated
This element is deprecated. Do not include in request.
payorAccountReference
Numeric20
Required
Reference/ID value. This is often the customer account number from your system.
payorMemoInformation
Alphanumeric50
Memo information for the explanation of the transaction.
payorBankRoutingNumber
Numeric9
Required
Payor bank routing number.
payorBankAccountNumber
Numeric20
Required
Payor bank account number.
payorCheckNumber
Numeric10
Check number to appear on any printed check representing this transaction.
payorAccountType
Alpha1
Required
Account type of the payor, Checking or Savings.
Valid value(s): C, S
chargeAmount
Numeric11
Required
The net dollar amount paid by the payor.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc.
feeAmount
Numeric11
Required
Transaction fee amount. Fee amount to be added to the charge amount.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc.
Constraint(s): If no fee is to be added to this transaction a value of zero “0” still needs to be submitted.
transactionOrigin
Alpha3
Required
The origin of the transaction.
Valid value(s): EXT
payorTransactionType
Alpha1
Required
Type of transaction, Debit or Credit.
Valid value(s): D, C
achEntryCode
Alpha3
Required
The NACHA/ACH SEC code for how payment authorization was received. Options and descriptions can be found in the appendix.
processingDate
Date10
Required
This element represents the date the payment should be submitted to the ACH payment system.
Format: YYYY-MM-DD
secondaryTrace
Alphanumeric50
Location information about a company.

API Processing Result

processACHTransactionResponse

The following table describes the individual elements of the processACHTransactionResponse object. This object represents the results of a processed transaction.

Attribute Description
processingResult
Alpha5
The result of the transaction request.
Valid value(s):
OK - The transaction was processed successfully.
ERROR - The transaction failed.
resultMessage
Alpha256
Detailed explanation of the result of the processed transaction. If processingResult was ERROR this field will provide details about why the transaction processing failed.
transactionID
Numeric20
Order/Confirmation number to transaction. This is used as a reference to a particular transaction after submission to the PDCFlow system.
achTransaction
ObjectN/A
The transaction details that were contained in your original request.

API Processing Fault

Generally, the only time a fault should be thrown is if you can’t connect to our system, or if the soap package is malformed. Verify you can access our wsdl and that all required elements listed above are present in your request.

Transaction Inquiry

Retrieve the status details of a transaction you have previously submitted.

API Inquiry Request

echeckInquiryData

The following table describes the individual elements of the echeckInquiryData object.

Attribute Description
customerID
Numeric4
Required
A four digit customer ID that together with the securityKey uniquely identifies the customer requesting ACH transaction information.
securityKey
Alphanumeric128
Required
A password that together with the customerID uniquely identifies the customer requesting ACH transaction information.
primaryTrace
Numeric20
Required
Order/Confirmation number of the transaction being inquired upon. If following up on a transaction submitted using the standard transaction processing, this would be the transactionID.

API Inquiry Result

getECheckDataResponse

The following table describes the individual elements of the getECheckDataResponse object. An ACH transaction can have more than one status message at a time, so these values can have more than one instance in a response.

Attribute Description
status
Alpha12
Current state of check in the ACH payment cycle.
Valid value(s):
WAITING - transaction will be included in next batch
SUBMITTED - transaction has been submitted for processing
ACKNOWLEDGED - transaction has been accepted for processing
FUNDED - money has been deposited into your account
DEDUCTION - money has been taken from your account
VOID - transaction was cancelled prior to submission for processing
RETURNED - an exception occurred while processing transaction
CORRECTION - transaction was automatically corrected during processing
ERROR - an unknown error occurred while processing transaction
statusDate
DateTime21
The date and time the check was submitted to PDCFlow.
Format: YYYY-MM-DD HH:mm:SS.S
statusDescription
Alpha256
Extended description of the status
secondaryTrace
Alphanumeric32
Location information about a company.

API Inquiry Fault

Generally, the only time a fault should be thrown is if you can’t connect to our system, or if the soap package is malformed. Verify you can access our wsdl and that all required elements listed above are present in your request.

Transaction Status Inquiry

Retrieve a list of all status changes for all transactions since your last request.

API Update Inquiry Request

getECheckDataUpdates

The following table describes the individual elements of the getECheckDataUpdates object.

Attribute Description
customerID
Numeric4
Required
A four digit customer ID that together with the securityKey uniquely identifies the customer requesting ACH status information.
securityKey
Alphanumeric128
Required
A password that together with the customerID uniquely identifies the customer requesting ACH status information.

API Update Inquiry Result

getECheckDataUpdatesResponse

The following table describes the individual elements of the getECheckDataUpdatesResponse object.

Attribute Description
id
Numeric20
The transactionID
status
Alpha12
Current state of check in the ACH payment cycle.
Valid value(s):
WAITING - transaction will be included in next batch
SUBMITTED - transaction has been submitted for processing
ACKNOWLEDGED - transaction has been accepted for processing
FUNDED - money has been deposited into your account
DEDUCTION - money has been taken from your account
VOID - transaction was cancelled prior to submission for processing
RETURNED - an exception occurred while processing transaction
CORRECTION - transaction was automatically corrected during processing
ERROR - an unknown error occurred while processing transaction
statusDate
DateTime21
The date and time the check was submitted to PDCFlow.
Format: YYYY-MM-DD HH:mm:SS.SM
statusDescription
Alpha256
Extended description of the status
secondaryTrace
Alphanumeric32
Location information about a company.

API Update Inquiry Fault

Generally, the only time a fault should be thrown is if you can’t connect to our system, or if the soap package is malformed. Verify you can access our wsdl and that all required elements listed above are present in your request.

Transaction Updating

Update the status of a previously submitted transaction. Currently, the only allowed method is to void a transaction. This will keep the transaction from being sent into the ACH network.

API Updating Request

eCheckUpdateData

The following table describes the individual elements of the eCheckUpdateData object.

Attribute Description
customerID
Numeric4
Required
A four digit customer ID that together with the securityKey uniquely identifies the customer requesting the update.
securityKey
Alphanumeric128
Required
A password that together with the customerID uniquely identifies the customer requesting the update.
primaryTrace
Numeric20
Required
Order/Confirmation number of the transaction being inquired upon. If following up on a transaction submitted using the standard transaction processing, this would be the transactionID.
newStatus
Alpha4
Required
New status to assign to the transaction.
Valid value(s): VOID

API Updating Result

updateStatusResponse

The following table describes the individual elements of the updateStatusResponse object.

Attribute Description
status
Alpha5
The status of the transaction.
Valid value(s):
OK - The transaction was processed successfully.
ERROR - The transaction failed.
resultMessage
Alpha256
Result of attempted update.

API Updating Fault

Generally, the only time a fault should be thrown is if you can’t connect to our system, or if the soap package is malformed. Verify you can access our wsdl and that all required elements listed above are present in your request. Common pieces to watch for are an incorrect namespace, missing one of the required 4 elements, or an element that is missing a value.

Sample Code

This section offers some client implementation examples in different languages. Keep in mind, these are only minimalistic examples used to demonstrate the Credit Card Services API and are not meant for production use.

processACHTransaction - Transaction Processing - individual transaction

<?php
// Get customer-specific information
$userInformation = [
  'pdcAccountSet' => '01',
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'userName' => 'frontenduser@pdc4u.com'
];

// Payment-specific information
$achInformation = [
  'payorFirstName' => 'Adam',
  'payorLastName' => 'Test',
  'payorStreetAddress1' => '1234 Main St.',
  'payorStreetAddress2' => 'Apt. 7B',
  'payorCity' => 'Ogden',
  'payorState' => 'UT',
  'payorZip' => '84404',
  'transactionEmailAddress' => 'adamemail@pdc4u.com',
  'payorPhoneNumber' => '777-777-7777',
  'payorAccountReference' => 'AB1234',
  'payorMemoInformation' => 'December payment',
  'payorBankRoutingNumber' => '124001545',
  'payorBankAccountNumber' => '123456',
  'payorCheckNumber' => '9999',
  'payorAccountType' => 'C',
  'chargeAmount' => '5.00',
  'feeAmount' => '0.50',
  'transactionOrigin' => 'EXT',
  'payorTransactionType' => 'D',
  'achEntryCode' => 'WEB',
  'processingDate' => '2017-05-31',
  'secondaryTrace' => ''
];

$url = 'https://achlegacydemo.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl';
$namespace = 'http://transaction.webservices.pdc4u.com';
$method = 'processACHTransaction';
$params = [
  'achTransaction' => $achInformation,
  'userInfo'=> $userInformation
];

$client = new SoapClient($url);

try {
  $response = $client->__soapCall(
    $method,
    [$params, $namespace]
  );

  print_r($response);
} catch (SoapFault $fault) {
  print_r($fault);
}
#!/usr/bin/perl

use SOAP::Lite +trace => 'debug';

my $soap = SOAP::Lite
   ->readable(1)
   ->autotype(0)
   ->ns( 'http://transaction.webservices.pdc4u.com/', "ns1" )
   ->proxy( 'https://achlegacydemo.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl' );

my %userInformation = (
  'pdcAccountSet' => '01',
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'userName' => 'frontenduser@pdc4u.com'
);

# Payment-specific information
my %achInformation = (
  'payorFirstName' => 'Adam',
  'payorLastName' => 'Test',
  'payorStreetAddress1' => '1234 Main St.',
  'payorStreetAddress2' => 'Apt. 7B',
  'payorCity' => 'Ogden',
  'payorState' => 'UT',
  'payorZip' => '84404',
  'transactionEmailAddress' => 'adamemail@pdc4u.com',
  'payorPhoneNumber' => '777-777-7777',
  'payorAccountReference' => 'AB1234',
  'payorMemoInformation' => 'December payment',
  'payorBankRoutingNumber' => '124001545',
  'payorBankAccountNumber' => '123456',
  'payorCheckNumber' => '9999',
  'payorAccountType' => 'C',
  'chargeAmount' => '5.00',
  'feeAmount' => '0.50',
  'transactionOrigin' => 'EXT',
  'payorTransactionType' => 'D',
  'achEntryCode' => 'WEB',
  'processingDate' => '2017-05-31',
  'secondaryTrace' => ''
);

my @transaction;
foreach my $key ( keys %achInformation ) {
   push @transaction, SOAP::Data->name( $key => $achInformation{$key} );
}

# userInfo
my @userInfo;
foreach my $key ( keys %userInformation ) {
   push @userInfo, SOAP::Data->name( $key => $userInformation{$key} );
}

print $soap->call( 'processACHTransaction',
   SOAP::Data->name('achTransaction' => \SOAP::Data->value(@transaction)),
   SOAP::Data->name('userInfo' => \SOAP::Data->value(@userInfo))
)->result;
#!/usr/bin/ruby

require 'savon' # version 2.0

begin
   # create a client for the service
   client = Savon.client(wsdl: 'https://achlegacydemo.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl',
      log_level: :debug,
      log: true,
      pretty_print_xml: true)

   puts "Available operations: "
   client.operations.each { |x| puts "   #{x}", "\n" } # find which operations are supported

   # Get customer-specific information
   userInformation = {
      'pdcAccountSet' => '01',
      'customerID' => '0000',
      'securityKey' => 'SomeSecurityKey',
      'userName' => 'frontenduser@pdc4u.com'
   }

   # Payment-specific information
   achInformation = {
      'payorFirstName' => 'Adam',
      'payorLastName' => 'Test',
      'payorStreetAddress1' => '1234 Main St.',
      'payorStreetAddress2' => 'Apt. 7B',
      'payorCity' => 'Ogden',
      'payorState' => 'UT',
      'payorZip' => '84404',
      'transactionEmailAddress' => 'adamemail@pdc4u.com',
      'payorPhoneNumber' => '777-777-7777',
      'payorAccountReference' => 'AB1234',
      'payorMemoInformation' => 'December payment',
      'payorBankRoutingNumber' => '124001545',
      'payorBankAccountNumber' => '123456',
      'payorCheckNumber' => '9999',
      'payorAccountType' => 'C',
      'chargeAmount' => '5.00',
      'feeAmount' => '0.50',
      'transactionOrigin' => 'EXT',
      'payorTransactionType' => 'D',
      'achEntryCode' => 'WEB',
      'processingDate' => '2017-05-31',
      'secondaryTrace' => ''
   }

   # Build the parameters
   params = {
      'achTransaction' => achInformation,
      'userInfo' => userInformation
   };

   response = client.call(:process_ach_transaction, message: params)

   puts response
rescue
   puts "Caught: #$!\n"
end

General transactions will use this method. It will simply accept ach details, and process the transaction.

The URL to process a check is:
test wsdl:
https://achlegacydemo.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl
live wsdl:
https://achlegacy.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl

The namespace to use is:
http://transaction.webservices.pdc4u.com

The method to use is:
processACHTransaction

processACHTransactionBatch - Transaction Processing - batch of transactions

<?php
// Get customer-specific information
$userInformation = [
  'pdcAccountSet' => '01',
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'userName' => 'frontenduser@pdc4u.com'
];

// Payment-specific information
$achInformation = [
  'payorFirstName' => 'Adam',
  'payorLastName' => 'Test',
  'payorStreetAddress1' => '1234 Main St.',
  'payorStreetAddress2' => 'Apt. 7B',
  'payorCity' => 'Ogden',
  'payorState' => 'UT',
  'payorZip' => '84404',
  'transactionEmailAddress' => 'adamemail@pdc4u.com',
  'payorPhoneNumber' => '777-777-7777',
  'payorAccountReference' => 'AB1234',
  'payorMemoInformation' => 'December payment',
  'payorBankRoutingNumber' => '124001545',
  'payorBankAccountNumber' => '123456',
  'payorCheckNumber' => '9999',
  'payorAccountType' => 'C',
  'chargeAmount' => '5.00',
  'feeAmount' => '0.50',
  'transactionOrigin' => 'EXT',
  'payorTransactionType' => 'D',
  'achEntryCode' => 'WEB',
  'processingDate' => '2017-05-31',
  'secondaryTrace' => ''
];

//Payment-specific information for tran 2
$achInformation2 = $achInformation;
$achInformation2['payorFirstName'] = 'Adam2';

$url = 'https://achlegacydemo.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl';
$namespace = 'http://transaction.webservices.pdc4u.com';
$method = 'processACHTransactionBatch';
$params = [
  'achTransactionBatchItems' => [
    $achInformation,
    $achInformation2
  ],
  'userInfo'=> $userInformation
];

$client = new SoapClient($url);

try {
  $response = $client->__soapCall(
    $method,
    [$params, $namespace]
  );

  print_r($response);
} catch (SoapFault $fault) {
  print_r($fault);
}
#!/usr/bin/perl

use SOAP::Lite +trace => 'debug';

my $soap = SOAP::Lite
   ->readable(1)
   ->autotype(0)
   ->ns( 'http://transaction.webservices.pdc4u.com/', "ns1" )
   ->proxy( 'https://achlegacydemo.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl' );

my %userInformation = (
  'pdcAccountSet' => '01',
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'userName' => 'frontenduser@pdc4u.com'
);

# Payment-specific information
my %achInformation = (
  'payorFirstName' => 'Adam',
  'payorLastName' => 'Test',
  'payorStreetAddress1' => '1234 Main St.',
  'payorStreetAddress2' => 'Apt. 7B',
  'payorCity' => 'Ogden',
  'payorState' => 'UT',
  'payorZip' => '84404',
  'transactionEmailAddress' => 'adamemail@pdc4u.com',
  'payorPhoneNumber' => '777-777-7777',
  'payorAccountReference' => 'AB1234',
  'payorMemoInformation' => 'December payment',
  'payorBankRoutingNumber' => '124001545',
  'payorBankAccountNumber' => '123456',
  'payorCheckNumber' => '9999',
  'payorAccountType' => 'C',
  'chargeAmount' => '5.00',
  'feeAmount' => '0.50',
  'transactionOrigin' => 'EXT',
  'payorTransactionType' => 'D',
  'achEntryCode' => 'WEB',
  'processingDate' => '2017-05-31',
  'secondaryTrace' => ''
);

my @batch1;
foreach my $key ( keys %achInformation ) {
   push @batch1, SOAP::Data->name( $key => $achInformation{$key} );
}

# Payment-specific information for tran 2
my %achInformation2 = %achInformation;
$achInformation2{'payorFirstName'} = 'Adam2';
my @batch2;
foreach my $key ( keys %achInformation2 ) {
   push @batch2, SOAP::Data->name( $key => $achInformation2{$key} );
}

# userInfo
my @userInfo;
foreach my $key ( keys %userInformation ) {
   push @userInfo, SOAP::Data->name( $key => $userInformation{$key} );
}

print $soap->call( 'processACHTransactionBatch',
   SOAP::Data->name('achTransactionBatchItems' => \SOAP::Data->value(@batch1)),
   SOAP::Data->name('achTransactionBatchItems' => \SOAP::Data->value(@batch2)),
   SOAP::Data->name('userInfo' => \SOAP::Data->value(@userInfo))
)->result;
#!/usr/bin/ruby

require 'savon' # version 2.0

begin
   # create a client for the service
   client = Savon.client(wsdl: 'https://achlegacydemo.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl',
      log_level: :debug,
      log: true,
      pretty_print_xml: true)

   puts "Available operations: "
   client.operations.each { |x| puts "   #{x}", "\n" } # find which operations are supported

   # Get customer-specific information
   userInformation = {
      'pdcAccountSet' => '01',
      'customerID' => '0000',
      'securityKey' => 'SomeSecurityKey',
      'userName' => 'frontenduser@pdc4u.com'
   }

   # Payment-specific information
   achInformation = {
      'payorFirstName' => 'Adam',
      'payorLastName' => 'Test',
      'payorStreetAddress1' => '1234 Main St.',
      'payorStreetAddress2' => 'Apt. 7B',
      'payorCity' => 'Ogden',
      'payorState' => 'UT',
      'payorZip' => '84404',
      'transactionEmailAddress' => 'adamemail@pdc4u.com',
      'payorPhoneNumber' => '777-777-7777',
      'payorAccountReference' => 'AB1234',
      'payorMemoInformation' => 'December payment',
      'payorBankRoutingNumber' => '124001545',
      'payorBankAccountNumber' => '123456',
      'payorCheckNumber' => '9999',
      'payorAccountType' => 'C',
      'chargeAmount' => '5.00',
      'feeAmount' => '0.50',
      'transactionOrigin' => 'EXT',
      'payorTransactionType' => 'D',
      'achEntryCode' => 'WEB',
      'processingDate' => '2017-05-31',
      'secondaryTrace' => ''
   }

   # Payment-specific information for tran 2
   achInformation2 = achInformation;
   achInformation2['payerFirstName'] = 'Adam2';

   # Build the parameters
   params = {
      'achTransactionBatchItems' => [
         achInformation,
         achInformation2
      ],
      'userInfo' => userInformation
   };

   response = client.call(:process_ach_transaction_batch, message: params)

   puts response
rescue
   puts "Caught: #$!\n"
end

You can also submit check transactions as a batch by providing a list of transactions.

The URL to process a check batch is:
test wsdl:
https://achlegacydemo.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl
live wsdl:
https://achlegacy.pdc4u.com/ECheckServices/ACHTransactionProcessor?wsdl

The namespace to use is:
http://transaction.webservices.pdc4u.com

The method to use is:
processACHTransactionBatch

getECheckData - Transaction Inquiry - get details about processed transactions

<?php
// Get customer and transaction information
$updateInformation = [
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'primaryTrace' => 'SomeTransactionID'
];

$url = 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckInquiry?wsdl';
$namespace = 'http://inquiry.webservices.pdc4u.com';
$method = 'getECheckData';
$params = [
  'echeckInquiryData'=> $updateInformation
];

$client = new SoapClient($url);

try {
  $response = $client->__soapCall(
    $method,
    [$params, $namespace]
  );

  print_r($response);
} catch (SoapFault $fault) {
  print_r($fault);
}
#!/usr/bin/perl

use SOAP::Lite +trace => 'debug';

my $soap = SOAP::Lite
   ->readable(1)
   ->autotype(0)
   ->ns( 'http://inquiry.webservices.pdc4u.com/', "ns1" )
   ->proxy( 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckInquiry?wsdl' );

# Get customer and transaction information
my %updateInformation = (
   'customerID' => '0000',
   'securityKey' => 'SomeSecurityKey',
   'primaryTrace' => 'SomeTransactionID'
);

print $soap->call( 'getECheckData',
   SOAP::Data->name('eCheckInquiryData' => \%updateInformation)
)->result;
#!/usr/bin/ruby

require 'savon' # version 2.0

begin
   # create a client for the service
   client = Savon.client(wsdl: 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckInquiry?wsdl',
      log_level: :debug,
      log: true,
      pretty_print_xml: true)

   puts "Available operations: "
   client.operations.each { |x| puts "   #{x}", "\n" } # find which operations are supported

   # Get customer and transaction information
   updateInformation = {
      'customerID' => '0000',
      'securityKey' => 'SomeSecurityKey',
      'primaryTrace' => 'SomeTransactionID'
   }

   # Build the parameters
   params = {
      'echeckInquiryData' => updateInformation
   }

   response = client.call(:get_e_check_data, message: params)

   puts response
rescue
   puts "Caught: #$!\n"
end

Gather information about a specific transaction.

The URL to check a transaction is:
test wsdl:
https://achlegacydemo.pdc4u.com/ECheckServices/ECheckInquiry?wsdl
live wsdl:
https://achlegacy.pdc4u.com/ECheckServices/ECheckInquiry?wsdl

The namespace to use is:
http://inquiry.webservices.pdc4u.com

The method to use is:
getECheckData

getECheckDataUpdates - Transaction Status Inquiry - get status changes since last request

<?php
// Get customer and transaction information
$updateInformation = [
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
];

$url = 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckUpdateInquiry?wsdl';
$namespace = 'http://inquiry.webservices.pdc4u.com';
$method = 'getECheckDataUpdates';
$params = [
  'echeckInquiryData'=> $updateInformation
];

$client = new SoapClient($url);

try {
  $response = $client->__soapCall(
    $method,
    [$params, $namespace]
  );

  print_r($response);
} catch (SoapFault $fault) {
  print_r($fault);
}
#!/usr/bin/perl

use SOAP::Lite +trace => 'debug';

my $soap = SOAP::Lite
   ->readable(1)
   ->autotype(0)
   ->ns( 'http://inquiry.webservices.pdc4u.com/', "ns1" )
   ->proxy( 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckUpdateInquiry?wsdl' );

# Get customer and transaction information
my %updateInformation = (
   'customerID' => '0000',
   'securityKey' => 'SomeSecurityKey',
);

print $soap->call( 'getECheckDataUpdates',
   SOAP::Data->name('echeckInquiryData' => \%updateInformation)
)->result;
#!/usr/bin/ruby

require 'savon' # version 2.0

begin
   # create a client for the service
   client = Savon.client(wsdl: 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckUpdateInquiry?wsdl',
      log_level: :debug,
      log: true,
      pretty_print_xml: true)

   puts "Available operations: "
   client.operations.each { |x| puts "   #{x}", "\n" } # find which operations are supported

   # Get customer and transaction information
   updateInformation = {
      'customerID' => '0000',
      'securityKey' => 'SomeSecurityKey',
   }

   # Build the parameters
   params = {
      'echeckInquiryData' => updateInformation
   }

   response = client.call(:get_e_check_data_updates, message: params)

   puts response
rescue
   puts "Caught: #$!\n"
end

Get details about all transactions since last request. It is recommended to use the Transaction Inquiry API rather than this method.

The URL to get status changes is:
test wsdl:
https://achlegacydemo.pdc4u.com/ECheckServices/ECheckUpdateInquiry?wsdl
live wsdl:
https://achlegacy.pdc4u.com/ECheckServices/ECheckUpdateInquiry?wsdl

The namespace to use is:
http://inquiry.webservices.pdc4u.com

The method to use is:
getECheckDataUpdates

updateStatus - Transaction Updating - change the status of a transaction

<?php
// Get customer and transaction information
$updateInformation = [
  'customerID' => '0000',
  'securityKey' => 'SomeSecurityKey',
  'primaryTrace' => 'SomeTransactionID',
  'newStatus' => 'VOID'
];

$url = 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckStatusUpdate?wsdl';
$namespace = 'http://update.webservices.pdc4u.com';
$method = 'updateStatus';
$params = [
  'eCheckUpdateData'=> $updateInformation
];

$client = new SoapClient($url);

try {
  $response = $client->__soapCall(
    $method,
    [$params, $namespace]
  );

  print_r($response);
} catch (SoapFault $fault) {
  print_r($fault);
}
#!/usr/bin/perl

use SOAP::Lite +trace => 'debug';

my $soap = SOAP::Lite
   ->readable(1)
   ->autotype(0)
   ->ns( 'http://update.webservices.pdc4u.com/', "ns1" )
   ->proxy( 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckStatusUpdate?wsdl' );

# Get customer and transaction information
my %updateInformation = (
   'customerID' => '0000',
   'securityKey' => 'SomeSecurityKey',
   'primaryTrace' => 'SomeTransactionID',
   'newStatus' => 'VOID'
);

print $soap->call( 'updateStatus',
   SOAP::Data->name('eCheckUpdateData' => \%updateInformation)
)->result;
#!/usr/bin/ruby

require 'savon' # version 2.0

begin
   # create a client for the service
   client = Savon.client(wsdl: 'https://achlegacydemo.pdc4u.com/ECheckServices/ECheckStatusUpdate?wsdl',
      log_level: :debug,
      log: true,
      pretty_print_xml: true)

   puts "Available operations: "
   client.operations.each { |x| puts "   #{x}", "\n" } # find which operations are supported

   # Get customer and transaction information
   updateInformation = {
      'customerID' => '0000',
      'securityKey' => 'SomeSecurityKey',
      'primaryTrace' => 'SomeTransactionID',
      'newStatus' => 'VOID'
   }

   # Build the parameters
   params = {
      'eCheckUpdateData' => updateInformation
   }

   response = client.call(:update_status, message: params)

   puts response
rescue
   puts "Caught: #$!\n"
end

Change the status of a previously submitted transaction. In particular, VOID the transaction.

The URL to update a transaction is:
test wsdl:
https://achlegacydemo.pdc4u.com/ECheckServices/ECheckStatusUpdate?wsdl
live wsdl:
https://achlegacy.pdc4u.com/ECheckServices/ECheckStatusUpdate?wsdl

The namespace to use is:
http://update.webservices.pdc4u.com

The method to use is:
updateStatus

GW Authentication API

The GWAuthenticationService is used for tasks related to authentication. This includes creating JWT’s for integration with specific webservices and creating API Keys for use with the TokenizationService. Authentication for the GWAuthenticationService will be done with BASIC HTTP Authorization. This includes passing a valid username and password in the header. In general, fields will only be returned if their value is not empty or null.

All requests that fail validation will return an HTTP response code 403 - Bad Request and a RequestErrorList containing details pertaining to the error(s).

Request Error List

Request Error List Object:

{
  "requestErrorList": [
    {
      "code": "ANF",
      "description": "API Key not found"
    }
  ]
}
Attribute Description
requestErrorList
ListN/A
A list of RequestError objects containing validation errors.
Details
 
code
Alpha3
The code for the validation error.
description
Alphanumeric255
The description of the validation error.

JWT

GET to retrieve list of schedule settings.

JWT Object

Full JWT Object

JWT Object:

{
  "accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0IiwiZXhwIjoxMDUwNTkxNjgyLCJqdGkiOiIzZGZjMzE5Ny01NjY3LTMzNDItYTZiNy01ZjVlMDQ4MjEyNWYiLCJpYXQiOjE1OTEzOTE2ODIsInNlcnZpY2VzIjpbeyJzZXJ2aWNlQWxsb3dTdGF0dXMiOiJBQ1RJVkUiLCJzZXJ2aWNlTmFtZSI6IkNBUkQifSx7InNlcnZpY2VBbGxvd1N0YXR1cyI6IkFDVElWRSIsInNlcnZpY2VOYW1lIjoiQ0hFQ0sifV0sImNvbXBhbnlBY3RpdmF0aW9uIjoiSU5BQ1RJVkUiLCAiTWVzc2FnZSI6IlRoYW5rcyBmb3IgZGVjb2RpbmcgYW5kIGNoZWNraW5nIG91dCB0aGlzIEpXVC4gSG9wZSB5b3UgbGlrZSBpdC4gVGhpcyBtZXNzYWdlIHdpbGwgbm90IGJlIGluIGEgUkVBTCBKV1QuIn0=.KRCSY7zHE5IeCnyGwrWooDgnxJjqJmQAH7uhq2hn8eU="
}
Attribute Description
accessToken
AlphaNumericN/A
The JWT that you will use to authenticate to PDCFlow Services.

–JWT Retrieval

GET :
test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/jwts
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/jwts

Use a username and password to obtain a JWT for use as authentication with other PDCFlow services. This API requires a Base64 encoded username:password, passed in through the BASIC Http Authorization Header. Other than the authorization header, there are no required attributes. An example is provided below.

Sample Response:

{
  "accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0IiwiZXhwIjoxMDUwNTkxNjgyLCJqdGkiOiIzZGZjMzE5Ny01NjY3LTMzNDItYTZiNy01ZjVlMDQ4MjEyNWYiLCJpYXQiOjE1OTEzOTE2ODIsInNlcnZpY2VzIjpbeyJzZXJ2aWNlQWxsb3dTdGF0dXMiOiJBQ1RJVkUiLCJzZXJ2aWNlTmFtZSI6IkNBUkQifSx7InNlcnZpY2VBbGxvd1N0YXR1cyI6IkFDVElWRSIsInNlcnZpY2VOYW1lIjoiQ0hFQ0sifV0sImNvbXBhbnlBY3RpdmF0aW9uIjoiSU5BQ1RJVkUiLCAiTWVzc2FnZSI6IlRoYW5rcyBmb3IgZGVjb2RpbmcgYW5kIGNoZWNraW5nIG91dCB0aGlzIEpXVC4gSG9wZSB5b3UgbGlrZSBpdC4gVGhpcyBtZXNzYWdlIHdpbGwgbm90IGJlIGluIGEgUkVBTCBKV1QuIn0=.KRCSY7zHE5IeCnyGwrWooDgnxJjqJmQAH7uhq2hn8eU="
}

Deprecated endpoint details

{
  "accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0IiwiZXhwIjoxMDUwNTkxNjgyLCJqdGkiOiIzZGZjMzE5Ny01NjY3LTMzNDItYTZiNy01ZjVlMDQ4MjEyNWYiLCJpYXQiOjE1OTEzOTE2ODIsInNlcnZpY2VzIjpbeyJzZXJ2aWNlQWxsb3dTdGF0dXMiOiJBQ1RJVkUiLCJzZXJ2aWNlTmFtZSI6IkNBUkQifSx7InNlcnZpY2VBbGxvd1N0YXR1cyI6IkFDVElWRSIsInNlcnZpY2VOYW1lIjoiQ0hFQ0sifV0sImNvbXBhbnlBY3RpdmF0aW9uIjoiSU5BQ1RJVkUiLCAiTWVzc2FnZSI6IlRoYW5rcyBmb3IgZGVjb2RpbmcgYW5kIGNoZWNraW5nIG91dCB0aGlzIEpXVC4gSG9wZSB5b3UgbGlrZSBpdC4gVGhpcyBtZXNzYWdlIHdpbGwgbm90IGJlIGluIGEgUkVBTCBKV1QuIn0=.KRCSY7zHE5IeCnyGwrWooDgnxJjqJmQAH7uhq2hn8eU=",
  "refreshToken": "deprecatedTokenWithNoUse"
}

test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/authentication
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/authentication

The Deprecated endpoint returns the accessToken as documented below, and also returns a refreshToken that is no longer used in any capacity.

API Key

POST to create new api key.
PUT to deactivate an existing api key by id.
GET to retrieve list of api keys.

Use a username and password to manage API keys. These keys will be used to authenticate use of the TokenizationService. You can retrieve a list of existing keys, create a new key, or revoke an existing key.

ApiKey Object

Full ApiKey Object

JWT Object:

{
    "companyCredentialApiKeyId": "1",
    "companyId": "1234",
    "createDateTime": "2019-01-01 05:12:12",
    "revokeDateTime": "",
    "lastUsedDateTime": "2020-01-01 12:09:14",
    "apiKey": "c5f84322-5e11-9080-3a66-ae0d2435673c"
}
Attribute Description
companyCredentialApiKeyId
Numeric8
The id of the API key. This will be used if you wanted to revoke access to a key.
companyId
Numeric8
The id of the company that owns the key. This will be your company id.
createDateTime
Datetime19
The date the key was created.
revokeDateTime
Datetime19
The date the key was revoked. No value if the key is still active.
lastUsedDateTime
Datetime19
The date when this key was last used for tokenization.
apiKey
Alphanumeric64
The API key to be used when attempting to tokenize a card.

–Api key list retrieval

GET : test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/apikeys


Sample Response:

{
  "apiKeyList": [
    {
        "companyCredentialApiKeyId": "1",
        "companyId": "1234",
        "createDateTime": "2019-01-01 05:12:12",
        "revokeDateTime": "",
        "lastUsedDateTime": "2020-01-01 12:09:14",
        "apiKey": "c5f84322-5e11-9080-3a66-ae0d2435673c"
    },
    {
        "companyCredentialApiKeyId": "2",
        "companyId": "1234",
        "createDateTime": "2019-01-01 09:12:12",
        "revokeDateTime": "2020-01-01 12:09:14",
        "lastUsedDateTime": "2020-01-01 04:09:14",
        "apiKey": "c5f81234-5e11-1234-3a66-ae0d2435673c"
    }
  ]
}

GET to retrieve a full list of all active and revoked API keys. There are no required parameters. View example request.

API Response

Attribute Description
apiKeyList
ListN/A
A list of apiKeyList objects containing details about each key.
Api Key Object
 
companyCredentialApiKeyId
Numeric8
The id of the API key. This will be used if you wanted to revoke access to a key.
companyId
Numeric8
The id of the company that owns the key. This will be your company id.
createDateTime
Datetime19
The date the key was created.
revokeDateTime
Datetime19
The date the key was revoked. No value if the key is still active.
lastUsedDateTime
Datetime19
The date when this key was last used for tokenization.
apiKey
Alphanumeric64
The API key to be used when attempting to tokenize a card.

–Create new key

POST to have a new key created. There are no required parameters. View example request.

POST : test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/apikeys

Sample Response:

{
    "companyCredentialApiKeyId": "3",
    "companyId": "1234",
    "createDateTime": "2020-06-01 05:12:12",
    "revokeDateTime": "",
    "lastUsedDateTime": "2020-01-01 12:09:14",
    "apiKey": "c5f84322-5e11-9080-3a66-ae0d2435673c"
}
Attribute Description
companyCredentialApiKeyId
Numeric8
The id of the API key. This will be used if you wanted to revoke access to a key.
companyId
Numeric8
The id of the company that owns the key. This will be your company id.
createDateTime
Datetime19
The date the key was created.
revokeDateTime
Datetime19
The date the key was revoked. No value if the key is still active.
lastUsedDateTime
Datetime19
The date when this key was last used for tokenization.
apiKey
Alphanumeric64
The API key to be used when attempting to tokenize a card.

–Revoke existing key

PUT test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys/{id}
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/apikeys/{id}

PUT to revoke an existing key. The key revoked will no longer be able to be used, effective immediately.
The companyCredentialApiKeyId should be used as the numeric id submitted to revoke an apiKey. If the key to specified to be revoked is the last active key, it will not be revoked. Instead, an Http Response Code 409 will be returned. View example request.

Sample Response:

{
    "companyCredentialApiKeyId": "2",
    "companyId": "1234",
    "createDateTime": "2019-01-01 05:12:12",
    "revokeDateTime": "",
    "lastUsedDateTime": "2020-01-01 12:09:14",
    "apiKey": "c5f84322-5e11-9080-3a66-ae0d2435673c"
}

Click to view object definition
Attribute Description
companyCredentialApiKeyId
Numeric8
The id of the API key. This will be used if you wanted to revoke access to a key.
companyId
Numeric8
The id of the company that owns the key. This will be your company id.
createDateTime
Datetime19
The date the key was created.
revokeDateTime
Datetime19
The date the key was revoked. No value if the key is still active.
lastUsedDateTime
Datetime19
The date when this key was last used for tokenization.
apiKey
Alphanumeric64
The API key to be used when attempting to tokenize a card.

Sample Code

This section offers some client implementation examples in different programming languages. Keep in mind, these are only minimalistic examples used to demonstrate the GWAuthentication Service REST API and are not meant for production use.

Result Status Codes

Expected Http Status codes

Status '200':
Description = 'Success.'

Status: '400':
Description = 'Malformed request. The request is either incorrectly formatted, or there are validation errors.'

Status '401':
Description = 'Invalid credentials.'

Status '404':
Description = 'The requested signature/document/image was not found.'

Status '405':
Description = 'POST, GET, PUT request not supported for resource.'

Status '409':
Description = 'Conflict. The resource could not be modified.'

Status '500':
Description = 'An internal error has occurred.'

Sample Retrieve new JWT

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;

namespace RestClient {

    public class Jwt {
        public string accessToken { get; set; }
    }

    public class MainClass {
        private HttpClient client = new HttpClient();

        private static void Main(string[] args) {
            string url = "https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/jwts";
            GETData(url);

            //Dispose once all HttpClient calls are complete. This is not necessary if the containing object will be disposed of; for example in this case the HttpClient instance will be disposed automatically when the application terminates so the following call is superfluous.
            client.Dispose();
        }


        private Jwt GETData(string url) {    
            // Add authentication header (base64Encoded username:password)
            var byteArray = Encoding.ASCII.GetBytes("username:password");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

            Jwt jwt = null;
            HttpResponseMessage response = await client.GetAsync(new Uri(url));
            if (response.IsSuccessStatusCode) {
                jwt = await response.Content.ReadAsAsync<jwt>();
            }

            /*
             * When using the .NET WebClient or HTTPWebRequest API’s, the actual response content on a bad HTTP status code response (for example, 400) is not parsed. If using these libraries, it is recommended to catch a WebException and force it to read the full stream allowing the JSON response body to be read.
             */

            return jwt;
        }
    }

}
<?php
$url = 'https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/jwts';

$curl = curl_init();

curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  //Handle success
}
else {
  //Handle error according to status code
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

   my $uri = URI->new("https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/jwts");

   my $req = HTTP::Request->new( 'GET', $uri );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

   url = "https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/jwts"

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

Creates a new JWT accessToken.

Send an HTTP GET request to:
test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/jwts
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/jwts

Sample List API keys

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;

namespace RestClient {

    public class MainClass {
        private HttpClient client = new HttpClient();

        private static void Main(string[] args) {
            string url = "https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys";
            GETData(url);

            //Dispose once all HttpClient calls are complete. This is not necessary if the containing object will be disposed of; for example in this case the HttpClient instance will be disposed automatically when the application terminates so the following call is superfluous.
            client.Dispose();
        }


        private bool GETData(string url) {    
            // Add authentication header (base64Encoded username:password)
            var byteArray = Encoding.ASCII.GetBytes("username:password");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

            HttpResponseMessage result = client.GetAsync(new Uri(url)).Result;

            /*
             * When using the .NET WebClient or HTTPWebRequest API’s, the actual response content on a bad HTTP status code response (for example, 400) is not parsed. If using these libraries, it is recommended to catch a WebException and force it to read the full stream allowing the JSON response body to be read.
             */

            if (result.StatusCode == System.Net.HttpStatusCode.Created) {
                //parse the response
                var dataObjects = response.Content.ReadAsAsync < IEnumerable < DataObject >> ().Result;  //Make sure to add a reference to System.Net.Http.Formatting.dll
                foreach(var d in dataObjects) {
                    Console.WriteLine("{0}", d.apikey);
                }
            }
        }
    }

}
<?php
$url = 'https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys';

$curl = curl_init();

curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  //Handle success
}
else {
  //Handle error according to status code
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

   my $uri = URI->new("https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys");

   my $req = HTTP::Request->new( 'GET', $uri );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

   url = "https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys"

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

Retrieve a list of existing API keys. Send an HTTP GET request to:
test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/apikeys

Sample Add API key

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;

namespace RestClient {

    public class MainClass {
        private HttpClient client = new HttpClient();

        private static void Main(string[] args) {
            string url = "https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys";
            POSTData(url);

            //Dispose once all HttpClient calls are complete. This is not necessary if the containing object will be disposed of; for example in this case the HttpClient instance will be disposed automatically when the application terminates so the following call is superfluous.
            client.Dispose();
        }


        private bool POSTData(string url) {    
            // Add an Accept header for JSON format.
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // Add authentication header (base64Encoded username:password)
            var byteArray = Encoding.ASCII.GetBytes("username:password");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

            /*
             * When using the .NET WebClient or HTTPWebRequest API’s, the actual response content on a bad HTTP status code response (for example, 400) is not parsed. If using these libraries, it is recommended to catch a WebException and force it to read the full stream allowing the JSON response body to be read.
             */

            HttpResponseMessage response = await client.PostAsync(new Uri(url), null);
            response.EnsureSuccessStatusCode();
        }
    }

}
<?php
$url = 'https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys';

$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode([], JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: 0'
  ]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  //Handle success
}
else {
  //Handle error according to status code
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting
use File::Slurp;
use MIME::Base64;

eval {
   my $data = {};
   $data = JSON::XS->new->utf8->encode ($data);

   my $url = 'https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys';

   my $req = HTTP::Request->new( 'POST', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin
   data = {}

   c = Curl::Easy.new
   c.url = 'https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys';
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_post(payload)

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

Add a new API key. Send an HTTP POST request to:
test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/apikeys

Sample Revoke API key

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;

namespace RestClient {

    public class MainClass {
        private HttpClient client = new HttpClient();

        private static void Main(string[] args) {
            int apikeyId = 1234; //The id of the apikey to revoke
            string url = "https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys/"+ apikeyId;
            PUTData(url);

            //Dispose once all HttpClient calls are complete. This is not necessary if the containing object will be disposed of; for example in this case the HttpClient instance will be disposed automatically when the application terminates so the following call is superfluous.
            client.Dispose();
        }


        private bool PUTData(string url) {    
            // Add an Accept header for JSON format.
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // Add authentication header (base64Encoded username:password)
            var byteArray = Encoding.ASCII.GetBytes("username:password");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

            /*
             * When using the .NET WebClient or HTTPWebRequest API’s, the actual response content on a bad HTTP status code response (for example, 400) is not parsed. If using these libraries, it is recommended to catch a WebException and force it to read the full stream allowing the JSON response body to be read.
             */

            HttpResponseMessage response = await client.PutAsync(new Uri(url));
            response.EnsureSuccessStatusCode();
        }
    }

}
<?php
$companyCredentialApiKeyId = 1;
$url = 'https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys/' . $companyCredentialApiKeyId;


$curl = curl_init();

curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
$data = json_encode([], JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data)
  ]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  //Handle success
}
else {
  //Handle error according to status code
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting
use File::Slurp;
use MIME::Base64;

eval {
   my $companyCredentialApiKeyId = 1;
   my $url = "https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys/$companyCredentialApiKeyId";

   my $data = {};
   $data = JSON::XS->new->utf8->encode ($data);

   my $req = HTTP::Request->new( 'PUT', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin
#   companyCredentialApiKeyId = 1;
   companyCredentialApiKeyId = 2560;
   url = "https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys/#{companyCredentialApiKeyId}"

   data = {}


   c = Curl::Easy.new
   c.url = url
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers = {}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_put(payload)

   #puts JSON.parse c.body_str
   puts c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

Revoke an existing API key. Send an HTTP PUT request to:
test wsdl:
https://authenticationdemo.pdc4u.com/GWAuthentication/api/v1_0/apikeys
live wsdl:
https://authentication.pdc4u.com/GWAuthentication/api/v1_0/apikeys

IVR Service API

This service allows you to create a tokenKey which is a pointer to a storage location used by the automated phone system to get card information from a consumer. You will then use the tokenKey to retrieve the tokenized card information after the phone call has completed.

A tokenKey is a pointer to a secure storage location used by the automated phone system to store tokenized card data. You will use the tokenKey whenever you need to retrieve this tokenized data.

Authentication and authorization for the IVRService will be done by JWT in the HTTP Authorization Header. This JWT can be obtained by passing a valid username and password to the GWAuthenticationService.

Token Keys

POST to retrieve a new token key.

Request Parameters

test wsdl:
https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys
live wsdl:
https://ivr.pdc4u.com/IVRService/api/v1_0/tokenkeys

Attribute Description
timeout
Numeric
Required
The number of minutes the token key is allowed to be updated with tokenized information.
roundTripNVPS
ListN/A
List of roundTripNVP objects. These are Name/Value passthrough values.
See object definition below.

Response

Attribute Description
tokenKey
Alphanumeric20
This will be used to retrieve the saved tokenized data.
responseStatus
Alpha7
The tokenKey returned from the POST request.
Valid values:
SUCCESS - See responseMessage for description.
ERROR - See responseMessage for description of error.
responseMessage
AlphanumericN/A
Description of the responseStatus.

GET to retrieve tokenized information

test wsdl:
https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys/{tokenkey}
live wsdl:
https://ivr.pdc4u.com/IVRService/api/v1_0/tokenkeys/{tokenkey}

Request Parameters

Attribute Description
tokenKey
Alphanumeric20
Required
The tokenKey returned from the POST request.

Response

Attribute Description
token
Alphanumeric16
The tokenized card number.
tokenType
Alpha15
The type of data that was tokenized.
Valid values:
CARD - Card number.
responseStatus
Alpha7
The tokenKey returned from the POST request.
Valid values:
SUCCESS - See responseMessage for description.
ERROR - See responseMessage for description of error.
responseMessage
AlphanumericN/A
Description of the responseStatus.
roundTripNVPS
ListN/A
List of roundTripNVP objects. These are Name/Value passthrough values.
See object definition below. This will include any roundTripNVP objects that were passed with the original POST request, and will also include:
expirationMonth - Card expiration month
expirationYear - Card expiration year
CardType - Card type

RoundTripNVP

Attribute Description
rtName
Alphanumeric75
Required
The name of a round trip name value pair.
rtValue
Alphanumeric75
Required
The value of a round trip name value pair.

REST Fault

RequestErrorList

Attribute Description
requestErrorList
ListN/A
A list of RequestError objects containing validation errors.
Constraint(s): Only returned when validation errors occur. See object definition below.

RequestError

Attribute Description
code
Alpha3
The code for the validation error.
description
AlphanumericN/A
The description of the validation error.

Sample Code

This section offers some client implementation examples in different languages. Keep in mind, these are only minimalistic examples used to demonstrate the IVR Service REST API and are not meant for production use. Endpoints are secured via Authentication JWT

Result Status Codes

Expected Http Status codes

Status '200':
Description = 'Success.'

Status: '400':
Description = 'Malformed request. The request is either incorrectly formatted, or there are validation errors.'

Status '401':
Description = 'Invalid credentials.'

Status '403':
Description = 'Service not activated.'

Status '404':
Description = 'The requested signature/document/image was not found.'

Status '405':
Description = 'POST, GET, PUT request not supported for resource.'

Status '498'
Description = 'JWT validation token is expired'

Status '500':
Description = 'An internal error has occurred.'

Status '503':
Description = 'The requested service (IVR, TOKENIZE) is not activated.'

All requests will return a status code. For example, in the case of status code 400, check for a requestErrorList in the response, containing information on validation failure.

Sample Token key generation

<?php
    $url = 'https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys?';

    $jwt = 'jwt_from_gwauthenticationservice';
    $authorization = "Authorization: Bearer " . $jwt;

    $data = [
      'timeout' => '30'
    ];


    $curl = curl_init();
    curl_setopt($curl, CURLOPT_POST, 1);
    $data = json_encode($data, JSON_UNESCAPED_SLASHES);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', $authorization));
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);  //num seconds to try connecting
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

    $result = curl_exec($curl);

    $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    // View response
    print_r(json_decode($result, true));

    if ($statusCode == '200')
    {
      //Handle success
    }
    else
    {
        //Handle error according to status code
    }
    curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $data = {
      'timeout' => '30'
   };

   $data = JSON::XS->new->utf8->encode ($data);

   my $url = 'https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys';

   my $jwt = 'jwt_from_gwauthenticationservice';
   my $authHeader = HTTP::Headers->new('Authorization' => 'Bearer '. $jwt);
   my $req = HTTP::Request->new( 'POST', $url, $authHeader );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin
   data = {
      'timeout' => '30'
   }

   jwt = 'jwt_from_gwauthenticationservice'

   c = Curl::Easy.new
   c.url = 'https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys'
   c.headers["Authorization: Bearer"] = jwt
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_post(payload)

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

Send an HTTP POST request to:
test wsdl:
https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys
live wsdl:
https://ivr.pdc4u.com/IVRService/api/v1_0/tokenkeys

Sample Tokenized data retrieval

<?php
    $url = 'https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys/';

    $jwt = 'jwt_from_gwauthenticationservice';
    $authorization = "Authorization: Bearer " . $jwt;

    $reportParams = [
      'tokenKey' => '4q3zmwd3n66'
    ];



    $url .= $reportParams['tokenKey'];

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', $authorization));
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);  //num seconds to try connecting
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

    $result = curl_exec($curl);

    $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    // View response
    print_r(json_decode($result, true));

    if ($statusCode == '200')
    {
      //Handle success
    }
    else
    {
        //Handle error according to status code
    }
    curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

   my $uri = URI->new("https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys/4q3zmwd3n66");

   my $jwt = 'jwt_from_gwauthenticationservice';
   my $authHeader = HTTP::Headers->new('Authorization' => 'Bearer '. $jwt);

   my $req = HTTP::Request->new( 'GET', $uri, $authHeader );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

   jwt = 'jwt_from_gwauthenticationservice'

   url = "https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys/4q3zmwd3n66"

   c = Curl::Easy.new( url )
   c.headers["Authorization: Bearer"] = jwt
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

Send an HTTP GET request to:
test wsdl:
https://ivrdemo.pdc4u.com/IVRService/api/v1_0/tokenkeys
live wsdl:
https://ivr.pdc4u.com/IVRService/api/v1_0/tokenkeys

Notification Service API

The Notification Service allows easy integration for getting data about Emails and SMS Notifications.

Authentication and authorization for the NotificationService will be done with a Base64 encoded username:password, passed in through the BASIC HTTP Authorization Header.

General Service Notes

GET Retrieve a single entity or a list of entities.
RESPONSE In general, fields will only be returned if their value is not null or empty.


Email Configuration


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/configure
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/emails/configure

Enable or Disable Email OptOut
A POST will create or update a ConfigureMail object.
A GET will retrieve a ConfigureMail object for the companyId provided.

ConfigureMail Object

Attribute Description
useOptOut
boolean
Should the company use the email OptOut logic.

Email Validate


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/validate
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/emails/validate

Validate a list of email addresses to check if they have Opted Out or Bounced.

POST an EmailAddressList object to see which email addresses have Opted Out or Bounced

If all valid an HttpStatus 200 is returned.
If any/all invalid an HttpStatus 400 is returned.

Any failures will be returned in a RequestErrorList object with an error and description for each invalid email address

Request EmailAddressList

Attribute Description
emailAddressList
Alphanumeric List75
The list of Email Addresses to validate.



Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/blocked/search
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/emails/blocked/search

POST EmailBlockedSearchParameters to this url to get an EmailBlockedList containing all blocked email addresses that match the search parameters.

Request EmailBlockedSearchParameters

Attribute Description
emailAddressList
Alphanumeric List75
A list of email addresses to filter the search by.
startDate
Alphanumeric19
Starting date to limit the search by.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
endDate
Alphanumeric19
Ending date to limit the search by.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
reasonList
ListN/A
Filters results by the listed blocked reason(s). If this value is not included, results will contain emails that have been OPTED_OUT and BOUNCED.
Valid values:
OPTED_OUT
BOUNCED
Note: Other values will be ignored.
recordCount
NumericN/A
Limits the number of records returned by the search.
Default: 2000
Max: 5000
recordStart
NumericN/A
Starting index of the returned results.
Default: 0

Response EmailBlockedList

Attribute Description
emailBlockedList
ListN/A
A list of EmailBlocked objects.

EmailBlocked

Attribute Description
companyId
Numeric8
The company id associated with the email address that has been blocked.
emailAddress
Alphanumeric75
The email address that has been blocked.
date
Alphanumeric19
The date the email address was blocked.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
reason
Alphanumeric19
The reason the email address was blocked.
Possible values:
OPTED_OUT - A user has opted out of receiving emails from this company id
BOUNCED - An email address was unable to be delivered

Email Unblock


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/unblock
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/emails/unblock

Unblock a list of email addresses. This will remove them from the Opted Out and/or Bounced list.
NOTE: This endpoint will ignore invalid email addresses and/or those not blocked.

POST an EmailAddressList object to unblock the email addresses.

HttpStatus 200 is returned for a valid request.
HttpStatus 400 is returned for an invalid request. Errors will be provided in a RequestErrorList object.

Request EmailAddressList

Attribute Description
emailAddressList
Alphanumeric List75
The list of Email Addresses to unblock.


SMS Validate


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/validate/{phoneNumber}
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/sms/validate/{phoneNumber}

Validate a phone number to check if they have Opted Out.

GET to see if the phone number has Opted Out

If valid an HttpStatus 200 is returned.
If invalid an HttpStatus 400 is returned.

A failure will be returned in a RequestErrorList object with an error and description for each invalid phone number


SMS Opt Out Reporting


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/optouts
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/sms/optouts

Request a list of all phone numbers opted out for the authenticated company.

GET a list of SmsOptOut objects to see which phone numbers have opted out of receiving SMS notifications

Request Parameters

Parameter Description
locationIdList
List - Numeric
Filters search by a list of locationId numeric values.

Response

List of SmsOptOut objects.

SmsOptOut Object

Parameter Description
dateOptOut
Datetime
The date the userPhone was opted out.
Format: yyyy-MM-dd HH:mm:ss
userPhone
Phone
The phone number of the opted out user.
Format Example: +18015551234
notificationPhone
Phone
The phone number to which an opt out request was sent. A user can text this number with Start to opt back in.
Format Example: +18015551234
locationId
Numeric
The locationId from which the userPhone is opted out. If this field is empty, an opt out applies to the company level. Otherwise, the opt out applies to the specified locationId.



REST Fault

RequestErrorList

Attribute Description
requestErrorList
ListN/A
A list of RequestError objects containing errors.
Constraint(s): Only returned when errors occur.

RequestError

Attribute Description
code
Alpha3
The code for the validation error.
errorCode
Numeric5
The error code of the validation error.
description
AlphanumericN/A
The description of the validation error.
retriable
Boolean5
Boolean to specify if the same request can be retried. This indicates a temporary failure.
apiFieldNameList
ListN/A
List of ApiFieldName with the specified RequestError

ApiFieldName

Attribute Description
apiFieldName
Alphanumeric
The name of the Api Field.
apiFieldValue
Alphanumeric
The value of the Api Field. When the Api Field is a list, this will show the specific list value which failed.



Sample Code

This section offers some client implementation examples in different languages. Keep in mind, these are only minimalistic examples used to demonstrate the Notification Service REST API and are not meant for production use.

Result Status Codes

Expected Http Status codes

Status '200':
Description = 'Success.'

Status: '400':
Description = 'Malformed request. The request is either incorrectly formatted, or there are validation errors.'

Status '401':
Description = 'Invalid credentials.'

Status '403':
Description = 'Service not activated.'

Status '404':
Description = 'The requested resource was not found.'

Status '500':
Description = 'An internal error has occurred.'

All requests will return a status code. For example, in the case of status code 400, check for a requestErrorList in the response, containing information on validation failure.

Sample Email Validate

<?php
$url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/validate';

$data = [
  'emailAddressList' => [
    'email1@example.com',
    'email2@example.com'
  ]
];

$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
  ]);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);

$result = curl_exec($curl);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
    my $data = {
        'emailAddressList' => {
            'email1@example.com',
            'email2@example.com'
        }
    }

    $data = JSON::XS->new->utf8->encode ($data);
    my $url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/validate';

    my $req = HTTP::Request->new( 'POST', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    data = {
        'emailAddressList' => {
            'email1@example.com',
            'email2@example.com'
        }
    }

    c = Curl::Easy.new
    c.url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/validate'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = data.to_json.length
    payload = data.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

POST an EmailAddressList object to see which email addresses have Opted Out or Bounced


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/validate
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/emails/validate

<?php
$url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/blocked/search';

$data = [
  'emailAddressList': [
    'email1@example.com',
    'email2@example.com'
  ],
  'startDate': '2021-08-01 00:00:00',
  'endDate': '2021-08-09 23:59:59',
  'reasonList': [
    'OPTED_OUT'
  ],
  'recordCount': 5000,
  'recordStart': 0
];

$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
  ]);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);

$result = curl_exec($curl);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
    my $data = {
        'emailAddressList': {
            'email1@example.com',
            'email2@example.com'
        },
        'startDate': '2021-08-01 00:00:00',
        'endDate': '2021-08-09 23:59:59',
        'reasonList': {
            'OPTED_OUT'
        },
        'recordCount': 5000,
        'recordStart': 0
    }

    $data = JSON::XS->new->utf8->encode ($data);
    my $url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/blocked/search';

    my $req = HTTP::Request->new( 'POST', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    data = {
        'emailAddressList': {
            'email1@example.com',
            'email2@example.com'
        },
        'startDate': '2021-08-01 00:00:00',
        'endDate': '2021-08-09 23:59:59',
        'reasonList': {
            'OPTED_OUT'
        },
        'recordCount': 5000,
        'recordStart': 0
    }

    c = Curl::Easy.new
    c.url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/email/validate'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = data.to_json.length
    payload = data.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

POST EmailBlockedSearchParameters to search for email addresses that have been blocked


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/blocked/search
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/emails/blocked/search

Sample Email Unblock

<?php
$url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/unblock';

$data = [
  'emailAddressList' => [
    'email1@example.com',
    'email2@example.com'
  ]
];

$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
  ]);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);

$result = curl_exec($curl);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
    my $data = {
        'emailAddressList' => {
            'email1@example.com',
            'email2@example.com'
        }
    }

    $data = JSON::XS->new->utf8->encode ($data);
    my $url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/unblock';

    my $req = HTTP::Request->new( 'POST', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    data = {
        'emailAddressList' => {
            'email1@example.com',
            'email2@example.com'
        }
    }

    c = Curl::Easy.new
    c.url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/unblock'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = data.to_json.length
    payload = data.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

POST an EmailAddressList object to unblock the email addresses


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/emails/unblock
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/emails/unblock

Sample SMS Validate

<?php
$url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/validate/1235551234';

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, [
  'Content-Type: application/json',
  "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword')
]);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $uri = URI->new("https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/validate/1235551234");

   my $req = HTTP::Request->new( 'GET', $uri );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

   url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/validate/1235551234'

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

GET to see if the phone number has Opted Out


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/validate/{phoneNumber}
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/sms/validate/{phoneNumber}

Sample SMS Opt Out Reporting

<?php
$url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/optouts?locationIdList=1111,1112';

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, [
  'Content-Type: application/json',
  "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword')
]);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $uri = URI->new("https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/optouts?locationIdList=1111,1112");

   my $req = HTTP::Request->new( 'GET', $uri );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

   url = 'https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/optouts?locationIdList=1111,1112'

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

GET a list of SmsOptOut objects to see which phone numbers have opted out of receiving SMS notifications


Test URL:
https://notificationdemo.pdc4u.com/NotificationService/api/v1_0/sms/optouts
Live URL:
https://notification.pdc4u.com/NotificationService/api/v1_0/sms/optouts

Portal API

The payment portal is the easiest way for you to accept online payments. We provide three ways to integrate:

For a more advanced integration, any option supports Postback Integration, which will automatically send you the data necessary to retrieve transaction details via Transaction Service. The Popup and Redirect options allow you to prepopulate the payment form (see Prepopulate Feature), which allows for a seamless integration to a PCI compliant payment portal.

Configure Portal

Portal Configuration URL:
test url: https://appdemo.pdcflow.com
live url: https://app.pdcflow.com

Since the payment portal is a feature of PDCflow’s FlowUI, all configuration of the payment portal needs to be done within our UI. Once you are signed in, go to Configure -> Portal. This will give you the ability to create any number of portals. Within each portal, you have the ability to configure multiple settings such as:

While this page gives a basic overview of portal setup, additional help can be found next to each setting on the configuration screen. Look for the purple question marks for a description of each setting.

Prepopulate Feature

One of the main features available to integrators is the ability to prepopulate a payment form. This is accomplished by handling all lookups within your existing system, and then using a POST to send that information into a PDC Portal.

The following table describes the individual elements that can receive a prepopulate value. If a portal configuration set a field to hidden, a prepopulate value for that field will be ignored.

Attribute Description
firstName
Alpha45
The first name of your client.
lastName
Alpha45
The last name of your client.
streetAddressOne
Alphanumeric80
The first line of the address.
streetAddressTwo
Alphanumeric45
The second line of the address.
city
Alphanumeric45
The city associated with the transaction.
state
Alpha2
The abbreviation of the state.
Format: two character abbreviation (UT, CA, MI, etc)
country
Alpha2
The abbreviation of the country. The only reason to set this parameter is if your client is outside of the United States.
Format: two character abbreviation (US, DE, GB, etc)
Default: US
zip
Numeric5
The zip code associated with the transaction.
zipPlusFour
Numeric4
The four digit extension of the zip code.
emailAddress
Alphanumeric75
The email address of the payer where a receipt will be sent at the completion of the transaction (if enabled in portal configuration).
phoneNumber
Alphanumeric10
Telephone number. All formatting should be removed, as only the first 10 digits will be used in the field.
Format: XXXXXXXXXX
accountNumber
Alphanumeric45
Account or reference number. This is often the customer account number from your system.
memo
Alphanumeric50
Custom memo information for the explanation of the transaction.
paymentAmount
Numeric11
The payment amount of the transaction.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc.
feeAmountCard
Numeric11
Fee to apply to a card payment. This will supersede any stored amount from the portal configuration. This will only apply if the Portal is set to use an amount based fee.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc.
feePercentCard
Numeric6
Fee to apply to a card payment. This will supersede any stored amount from the portal configuration. This will only apply if the Portal is set to use a percentage based fee. Send fee as a decimal value (i.e. 5% should be sent as 0.0500).
Format: X.XXXX
Do not use any formatting symbols such as currency symbols ($), commas etc.
feeAmountCheck
Numeric11
Fee to apply to a check payment. This will supersede any stored amount from the portal configuration. This will only apply if the Portal is set to use an amount based fee.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc.
feePercentCheck
Numeric6
Fee to apply to a check payment. This will supersede any stored amount from the portal configuration. This will only apply if the Portal is set to use a percentage based fee. Send fee as a decimal value (i.e. 5% should be sent as 0.0500).
Format: X.XXXX
Do not use any formatting symbols such as currency symbols ($), commas etc.
flowId
Numeric10
The related Flow transaction, often a signature. See Signature Service. This will not be visible on the screen to your users.
roundTrip
Alphanumeric75
This can be used to pass custom key/value pairs with each payment. For example, if you need to track the office a payment was processed through, that can be submitted as a roundTrip, and it will be included with the payment information at the end of processing. You may send up to 3. They should be passed as an html array. The key can be up to 75 characters, and the value can be up to 75 characters.

In the example below, the keys are level and office, and the values are A and Scranton.
Format:
<input type=“hidden” name=“roundTrip[level]” value=“A” />
<input type=“hidden” name=“roundTrip[office]” value=“Scranton” />
<form action="https://appdemo.pdcflow.com/customerID" method="post">
  <input type="submit" value="Payment by credit card" />
  <input type="hidden" name="firstName" value="Adam" /> <input type="hidden" name="lastName" value="Test" />
  <input type="hidden" name="accountNumber" value="AB1234" /> <input type="hidden" name="paymentAmount" value="5.00" />
  <input type="hidden" name="roundTrip[office]" value="Scranton" />
</form>

Use standard hidden fields to submit your information to PDC. This should always be sent as a POST request.

<div id="myForm">
  <form id="pdcPopulate" action="https://appdemo.pdcflow.com/customerID/" method="post" target="launchPdc">
    <input type="hidden" name="firstName" value="Adam" /> <input type="hidden" name="lastName" value="Test" />
    <input type="hidden" name="accountNumber" value="AB1234" />
    <input type="hidden" name="paymentAmount" value="5.00" />
    <input type="hidden" name="roundTrip[office]" value="Scranton" />
    <input type="submit" value="Pay Now" onclick="openWindow(); return false;">
  </form>
</div>
<div id="myWaiting" style="display:none;">
  Waiting for payment...
</div>
<div id="myResult" style="display:none;"></div>

<script>
  let pdcWindow = '';

  /**
   * @param {object} event
   * @param {object} event.data
   * @param {string} event.data.transactionStatus
   * @param {string} event.data.paymentMethod
   * @param {string} event.data.arrivalId
   * @param {string} event.data.transactionId
   */
  window.addEventListener('message', (event) => {
    if(event.origin === 'https://appdemo.pdcflow.com') {
      let myMessage;

      if(event.data.transactionStatus === 'APPROVED') {
        myMessage = 'Thank you for your payment<br />';
        myMessage += 'Result: ' + event.data.transactionStatus + '<br />';
        myMessage += 'Method: ' + event.data.paymentMethod + '<br />';
        myMessage += 'Arrival: ' + event.data.arrivalId + '<br />';
        myMessage += 'Transaction: ' + event.data.transactionId + '<br /><br />';
        myMessage += 'If you have your receipt, you can <a href="javascript:pdcWindow.close();">close the payment form</a> now';
      }
      else {
        myMessage = 'Uh-oh, something went wrong with your payment.  Try again?<br />';
        myMessage += 'Result: ' + event.data.transactionStatus;
      }

      document.getElementById('myResult').innerHTML = myMessage;
      document.getElementById('myResult').style.display = 'block';
      document.getElementById('myWaiting').style.display = 'none';
    }
  });

  function openWindow() {
    document.getElementById('myForm').style.display = 'none';
    document.getElementById('myWaiting').style.display = 'block';
    document.getElementById('myResult').innerHTML = '';
    document.getElementById('myResult').style.display = 'none';

    const h = screen.height * .7;
    const w = screen.width * .7;
    pdcWindow = window.open('', 'launchPdc', 'toolbar=no,left=100,top=100,menubar=no,width=' + w + ',height=' + h);
    document.getElementById('pdcPopulate').submit();

    if(pdcWindow === null) {
      alert('popup blocked');
    }
  }

  const loop = setInterval(function() {
    if(pdcWindow.closed) {
      clearInterval(loop);
      document.getElementById('myWaiting').style.display = 'none';

      if(document.getElementById('myResult').innerHTML === '') {
        document.getElementById('myForm').style.display = 'block';
        document.getElementById('myResult').innerHTML = 'User closed window prior to completing payment';
        document.getElementById('myResult').style.display = 'block';
      }
    }
  }, 1000);
</script>

A portal can be launched in a popup for a seamless user experience. Populating the portal is similar to the prior example, but needs to be handled a bit different. Standard hidden form fields plus a POST should still be used, but a target also needs to be included. All options listed in Prepopulate Feature are supported.

An additional method is available to receive an update on the result of the payment attempt. For each payment attempt, a message will be posted using the Window.postMessage() API. The same attributes as the Postback Integration will be sent.

Redirect Option

<div id="myForm">
  <form id="pdcPopulate" action="https://appdemo.pdcflow.com/customerID/" method="post">
    <input type="hidden" name="firstName" value="Adam" /> <input type="hidden" name="lastName" value="Test" />
    <input type="hidden" name="accountNumber" value="AB1234" />
    <input type="hidden" name="paymentAmount" value="5.00" />
    <input type="hidden" name="roundTrip[office]" value="Scranton" /> <input type="submit" value="Pay Now">
  </form>
</div>
  <?php
    if(!empty($_GET)) {
      if($_GET['transactionStatus'] == 'APPROVED') {
        echo 'Thank you for your payment<br />';
        echo 'Result: ' . $_GET['transactionStatus'] . '<br />';
        echo 'Method: ' . $_GET['paymentMethod'] . '<br />';
        echo 'Arrival: ' . $_GET['arrivalId'] . '<br />';
        echo 'Transaction: ' . $_GET['transactionId'];
      }
      else {
        echo 'Uh-oh, something went wrong with your payment.  Try again?<br />';
        echo 'Result: ' . $_GET['transactionStatus'];
      }
    }

In this redirect option, your user will leave your site, go to PDC, and then return to your site at the end. The URL to be returned to must be configured on the portal within FlowUI. The same attributes as the Postback Integration will be appended to your url. All options listed in Prepopulate Feature are supported.

Postback Integration

If an url is set within Configure Portal, basic information about a transaction can be posted back to your system. The information returned can be used to securely request further detail from Transaction Service. The content will always come as JSON, and as POST. A postback will occur after any success or failed payment.

If something goes wrong when attempting to postback to your system, PDC will automatically retry on the following schedule.

To be considered successful, we expect your server to return a status 200. Once that is received or after Attempt #5, we will no longer try to post the data back to you.

Attribute Description
arrivalId
Numeric20
The PDC transaction arrival id, always present. Use this to pull further details on a payment. Generally only needed if the payment request failed.
transactionId
Numeric20
The PDC transaction id. Only populated on an APPROVED transaction. Use this to pull further details on a payment, check the status, issue a CREDIT, etc. This value will only be present on a successful payment.
paymentMethod
Alpha5
The method of payment, always present.
Valid value(s): CARD, CHECK
transactionStatus
Alpha8
Result of the payment attempt, always present.
Valid value(s):
APPROVED - Transaction was processed successfully.
DECLINED - The transaction was sent to the vendor, but the vendor declined the transaction. These transactions will typically not be accepted regardless of how many times they are retried.
ERROR - An error has occurred and the transaction failed processing. These transactions can typically be resubmitted once the issues have been corrected.

Postback sample - successful payment

{
  "arrivalId": "1234",
  "transactionId": "5678",
  "paymentMethod": "CARD",
  "transactionStatus": "APPROVED"
}

After a successful payment, all 4 attributes will be populated.

Postback sample - failed payment

{
  "arrivalId": "1234",
  "transactionId": null,
  "paymentMethod": "CARD",
  "transactionStatus": "DECLINED"
}

On a failed payment attempt, only 3 of the 4 attributes will be populated.

Schedule Service API

The Schedule and Recurring service allows easy integration for creating, modifying, and retrieving of Schedule and Recurring information. Schedules are retrieved, created and modified through GET, POST, PATCH, and PUT requests.

Authentication and authorization for the ScheduleService will be done by JWT in the HTTP Authorization Header. This JWT can be obtained by passing a valid username and password to the GWAuthenticationService.

In general, fields will only be returned if their value is not null or empty.

All requests that fail validation will return an HTTP response code 403 - Bad Request and a RequestErrorList containing details pertaining to the error(s).

Request Error List

Request Error List Object:

{
  "requestErrorList": [
    {
      "code": "10028",
      "description": "Missing required field",
      "apiFieldNameList": [
        {
          "apiFieldName": "firstName"
        }
      ]
    },
    {
      "code": "10028",
      "description": "Missing required field",
      "apiFieldNameList": [
        {
          "apiFieldName": "owedAmount"
        }
      ]
    }
  ]
}
Attribute Description
requestErrorList
ListN/A
A list of RequestError objects containing validation errors.
Details
 
code
Numeric5
The code for the validation error.
description
Alphanumeric255
The description of the validation error.
apiFieldNameList
ListN/A
List of ApiFieldName objects that specify which api field this error relates to.
Details
 
apiFieldName
Alphanumeric255
The name of the Api Field that the error relates to.

The first step will be to save some settings that will be used in schedule creation.

Schedule Settings

POST to save new schedule setting.
PUT to overwrite a single schedule setting by settingId.
GET to retrieve list of schedule settings.
GET to retrieve single schedule setting by settingId.
GET to retrieve single schedule setting by name.
DELETE to delete single schedule setting by settingId.

ScheduleSetting Object

Full Setting Object

Setting Object:

{
  "settingId": 3,
  "companyId": 1234,
  "name": "MySettingName",
  "recurSetting": "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
  "date": "2018-01-01 12:00:00",
  "user": "testUser"
}
Attribute Description
settingId
Numeric 8
The id of the schedule setting.
companyId
Numeric 8
The company id of the company the setting belongs to.
name
Alpha 75
The name of the schedule setting.
description
Alphanumeric 255
Description of the schedule setting.
recurSetting
JSON65000
The recurring schedule settings.
date
Date19
The date the setting was updated.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
user
Alphanumeric75
The user that last updated the schedule setting.

–Setting Creation

POST :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings


Sample Response:

{
  "settingId": 4,
  "companyId": 1234,
  "name": "MySettingName",
  "recurSetting": "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
  "date": "2020-01-01 17:00:00",
  "user": "testUser"
}
Attribute Description
name
Alpha 75
Required
The name of the schedule setting. This must be unique.
description
Alphanumeric 255
Description of the schedule setting.
recurSetting
JSON
Required
The recurring schedule settings. This value must be a JSON encoded string.
Expected JSON fields
paymentTypes
ListN/A
Required
The schedule payment types in a list.
Valid value(s):
CHECK - schedules with check transactions will be allowed
CARD - schedules with card transactions will be allowed
minimumPaymentAmount
Numeric8
Required
The minimum payment allowed per payment on a schedule. This value must be between 1 and 10000.
allowedFrequencies
AlphaN/A
Required
The allowed payment frequencies, in a list.
Valid value(s):
MONTHLY - once per month
BI_MONTHLY - 2 times per month
BI_WEEKLY - once every 2 weeks
WEEKLY - once per week
DAILY - once per day
checkReminderDays
Numeric2
Required
The number of days prior to the payment date to send a reminder. The reminder will be sent to the associated email address. If the schedule has no email address, reminders will NOT be sent.
This value must be between 3 and 14.
cardReminderDays
Numeric2
Required
The number of days prior to the payment date to send a reminder. The reminder will be sent to the associated email address. If the schedule has no email address, reminders will NOT be sent.
This value must be between 3 and 14.
recurrenceRule
Alphanumeric255
Required
This is the recurrence rule that you want the schedules using this setting to calculate the payments against. This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. There is also no need to start a rule with “RRULE=” Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31.
maxDaysToStart
Numeric3
The number of days in the future that a schedule must start when providing DTSTART in the Schedule recurrenceRule. Defaults to 13 months if not provided.
user
Alphanumeric75
Required
The user that is creating the schedule setting.

–Setting Modification

PUT :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/{settingId}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/{settingId}


Sample Response:

{
  "settingId": 4,
  "companyId": 1234,
  "name": "MySettingNameUpdated",
  "recurSetting": "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
  "date": "2020-01-02 17:00:00",
  "user": "updatingUser"
}

PUT requests will completely override the existing specified (by settingId in the URL) setting. As such, the request object the same as the setting creation.

Setting Modification
Attribute Description
name
Alpha 75
Required
The name of the schedule setting. This must be unique.
description
Alphanumeric 255
Description of the schedule setting.
recurSetting
JSON65000
Required
The recurring schedule settings. This value must be a JSON encoded string.
Expected JSON fields
paymentTypes
ListN/A
Required
The schedule payment types in a list.
Valid value(s):
CHECK - schedules with check transactions will be allowed
CARD - schedules with card transactions will be allowed
minimumPaymentAmount
Numeric8
Required
The minimum payment allowed per payment on a schedule. This value must be between 1 and 10000.
allowedFrequencies
AlphaN/A
Required
The allowed payment frequencies, in a list.
Valid value(s):
MONTHLY - once per month
BI_MONTHLY - 2 times per month
BI_WEEKLY - once every 2 weeks
WEEKLY - once per week
DAILY - once per day
checkReminderDays
Numeric2
Required
The number of days prior to the payment date to send a reminder. The reminder will be sent to the associated email address. If the schedule has no email address, reminders will NOT be sent.
This value must be between 3 and 14.
cardReminderDays
Numeric2
Required
The number of days prior to the payment date to send a reminder. The reminder will be sent to the associated email address. If the schedule has no email address, reminders will NOT be sent.
This value must be between 3 and 14.
recurrenceRule
Alphanumeric255
Required
This is the recurrence rule that you want the schedules using this setting to calculate the payments against. This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. There is also no need to start a rule with “RRULE=” Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31.
maxDaysToStart
Numeric3
The number of days in the future that a schedule must start when providing DTSTART in the Schedule recurrenceRule. Defaults to 13 months if not provided.
user
Alphanumeric75
Required
The user that is creating the schedule setting.

–Setting Retrieval List

GET :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings


Sample Response:

[
  {
    "settingId": 2,
    "companyId": 1234,
    "name": "Name of a setting",
    "recurSetting": "{\"recurrenceRule\":\"FREQ=WEEKLY;INTERVAL=1;\",\"paymentTypes\":[\"CARD\"],\"minimumPaymentAmount\":\"100\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
    "date": "2019-11-09 01:01:01",
    "user": "betterTester"
  },
  {
    "settingId": 3,
    "companyId": 1234,
    "name": "Another setting",
    "recurSetting": "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=15;\",\"paymentTypes\":[\"CHECK\"],\"minimumPaymentAmount\":\"1000\",\"allowedFrequencies\":[\"MONTHLY\"],\"checkReminderDays\":\"13\",\"cardReminderDays\":\"13\"}",
    "date": "2019-11-19 12:00:00",
    "user": "anotherTester@test.com"
  },
  {
    "settingId": 4,
    "companyId": 1234,
    "name": "MySettingName",
    "recurSetting": "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
    "date": "2020-01-01 17:00:00",
    "user": "testUser"
  }
]

Retrieve a list of all previously saved schedule settings. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings

–Setting Retrieval Individual

GET :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/{id}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/{id}


Sample Response:

{
  "settingId": 4,
  "companyId": 1234,
  "name": "MySettingName",
  "recurSetting": "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
  "date": "2020-01-01 17:00:00",
  "user": "testUser"
}

Retrieve an individual schedule setting by settingId. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/4

–Setting Retrieval Name

GET :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/names/{name}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/names/{name}


Sample Response:

{
  "settingId": 4,
  "companyId": 1234,
  "name": "MySettingName",
  "recurSetting": "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
  "date": "2020-01-01 17:00:00",
  "user": "testUser"
}

Retrieve an individual schedule setting by name. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/names/MySettingName

–Setting Deletion

DELETE :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/{id}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/{id}

Delete an individual schedule setting by settingId. A setting cannot be deleted if it is associated with a schedule. This request will return no response body, rather just a standard HTTP status code 200 for successful deletion. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/4

Recurring Term

POST to create a new recurring term record.
PUT to modify an existing recurring term.
DELETE to delete an exiting recurring term.
GET to get a list of recurring terms or an individual term.

Recurring Terms can be used to restrict the run length of schedules within a specific owed amount range. For example, you can specify that schedules with an owed amount less than $1,000 can have a maximum length of 36 months. Specifying multiple recurring terms allows for different lengths of schedules for different amounts. Specifying a recurring term with no maximum amount would allow a maximum schedule duration to be specified for any schedule amount.

Recurring Term Object

Full Recurring Term Object

Recurring Term Object:

{
  "id": 3,
  "maximumAmount": 1000,
  "termMonth": 36,
  "date": "2020-01-01 12:00:00",
  "maximumPayments": 23,
  "user": "testUser"
}

Attribute Description
id
Numeric20
Id for the recurring term.
maximumAmount
Numeric12
Maximum amount for the term.
termMonth
AlphaNumeric3
The maximum amount of months a schedule with an owedAmount within the maximumAmount can run.
date
Date19
Date the term was last modified
Format: URL Encoded ISO-8601
user
AlphaNumeric75
User creating or modifying the record.
maximumPayments
Numeric
READONLY
The maximum amount of payments that can be created with this term and the recurrenceRule from the specified setting. Only returns when an amount and settingId are specified in the URL.

–Recurring Term Creation

POST :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms


Sample Response:

{
  "id": 3,
  "maximumAmount": 1000,
  "termMonth": 36,
  "date": "2020-01-01 12:00:00",
  "user": "testUser"
}
Attribute Description
maximumAmount
Numeric12
Maximum amount for the term. Leaving the amount blank will make the record unbounded. This value must be unique.
termMonth
AlphaNumeric3
Required
The maximum amount of months a schedule with an owedAmount within the maximumAmount can run.
user
AlphaNumeric75
Required
User creating or modifying the record.

–Recurring Term Modification

PUT :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/{recurringTermId}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/{recurringTermId}


Sample Response:

{
  "id": 3,
  "maximumAmount": 1000,
  "termMonth": 36,
  "date": "2020-01-01 12:00:00",
  "user": "testUser"
}

PUT requests will completely override the existing specified (by recurringTermId in the URL) recurring term. As such, the request object is the same as the recurring term creation.

Schedule Modification
Attribute Description
maximumAmount
Numeric12
Maximum amount for the term. Leaving the amount blank will make the record unbounded. This value must be unique.
termMonth
AlphaNumeric3
Required
The maximum amount of months a schedule with an owedAmount within the maximumAmount can run.
user
AlphaNumeric75
Required
User creating or modifying the record.

–Recurring Term Retrieval (List)

GET :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/


Sample Response:

{
  "recurringTerms": [
    {
      "id": 3,
      "maximumAmount": 1000,
      "termMonth": 36,
      "date": "2020-01-01 12:00:00",
      "user": "testUser"
    },
    {
      "id": 4,
      "termMonth": 48,
      "date": "2019-01-01 12:00:00",
      "user": "testUserHere"
    },
    {
      "id": 9,
      "maximumAmount": 20000,
      "termMonth": 36,
      "date": "2019-01-06 12:00:00",
      "user": "oneMoreUser"
    }
  ]
}

Retrieve an object with a list of all previously saved recurring terms. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms

–Recurring Term Retrieval (Individual)

GET :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/{id}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/{id}


Sample Response:

{
  "id": 9,
  "maximumAmount": 20000,
  "termMonth": 36,
  "date": "2019-01-06 12:00:00",
  "user": "oneMoreUser"
}

Retrieve an individual recurring term by recurringTermId. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringTerms/9

–Recurring Term Retrieval (By Amount)

GET :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/


Sample Response:

{
  "id": 3,
  "maximumAmount": 1000,
  "termMonth": 36,
  "date": "2020-01-01 12:00:00",
  "maximumPayments": "20",
  "user": "testUser"
}

Retrieve a recurring term based on a specified amount. This will return the term that would be used if a schedule with a specified amount were to be created. The maximumPayments is the maximum amount of payments that would be allowed for a schedule of the specified amount, based on the Setting specified. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms?amount=850

Attribute Description
amount
Numeric12
The amount to retrieve the recurring term for.
settingId
Numeric8
The setting that will be used for schedule creation. Passing this value, along with the amount, will allow the service to return the correct recurringTerm for the amount, and also the maximum number of payments possible for a schedule created using this settingId and this amount.
recurrenceRule
Alphanumeric255
This is the recurrence rule that you want the schedules using this setting to calculate the payments against. Providing this in this request will allow overriding of the recurrenceRule specified by the settingId and will calculate the maximum number of payments based on the amount and this recurrenceRule.
This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. There is also no need to start a rule with “RRULE=” Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31.

–Recurring Term Deletion

DELETE :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringTerms/{id}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringTerms/{id}

Delete an individual recurring term by recurringTermId. This request will return no response body, rather just a standard HTTP status code 200 for successful deletion. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringTerms/9

Schedule Preview

POST to create a preview of a schedule. This preview will not be saved until the schedules endpoint is called with a POST or a PUT request to save the schedule.

Schedule Preview Object

Complete Schedule Preview Object

Schedule Preview Object

{
  "owedAmount": 1500,
  "settingId": 14434,
  "initialPaymentAmount": 500,
  "adjustmentAmount": 500,
  "paymentAmount": 100,
  "numberOfPayments": 5,
  "payments": [
    {
      "status": "PENDING",
      "paymentAmount": 100,
      "paymentDate": "2020-02-01"
    },
    {
      "status": "PENDING",
      "paymentAmount": 100,
      "paymentDate": "2020-03-01"
    },
    {
      "status": "PENDING",
      "paymentAmount": 100,
      "paymentDate": "2020-04-01"
    },
    {
      "status": "PENDING",
      "paymentAmount": 100,
      "paymentDate": "2020-05-01"
    },
    {
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-06-01"
    }
  ]
}

Attribute Description
owedAmount
Numeric11
The original amount, or the amount owed by the debtor.
settingId
Numeric 8
The id of the schedule setting to be used to generate the schedule preview.
initialPaymentAmount
Numeric11
Conditional
An amount processed before the schedule is started. This will be deducted from the owedAmount. If processInitialPaymentOnActivation is true this amount is required and will be processed. Otherwise this amount will not be processed, and is on the schedule for reference only.
adjustmentAmount
Numeric11
An amount to be deducted from the owedAmount. This amount will not be processed by the schedule, but is on the schedule for reference only.
numberOfPayments
Numeric3
The number of payments desired for the schedule. If this is provided the paymentAmount cannot be provided. If the number of payments requested is too great, causing each payment to be less than the minimumPaymentAmount as specified by the ScheduleSetting, an error message will be provided that indicates the maximum number of payments.
paymentAmount
Numeric11
This is the amount that will be charged for each scheduled payment. If this is provided the numberOfPayments cannot be provided. If the payment amount is too small, causing the schedule length to exceed the termMonth for this amount, an error message will be provided that indicates the minimum value.
recurrenceRule
Alphanumeric255
This is the recurrence rule that you want the schedule to calculate the payments against. Passing in a recurrence rule here will override the recurrence that was saved as part of the ScheduleSetting referenced by the settingId. This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. Restrictions on which frequencies are allowed are stored in the ScheduleSetting object. There is no need to start a rule with “RRULE=”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31. Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”.
payments
ListN/A
List of SchedulePayment objects. Each SchedulePayment will include only a paymentAmount and paymentDate.

–Schedule Preview Creation

POST :
test urls:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/previews
live urls:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/previews


Sample Response:

{
  "owedAmount": 1500,
  "settingId": 14434,
  "initialPaymentAmount": 500,
  "adjustmentAmount": 500,
  "paymentAmount": 100,
  "numberOfPayments": 5,
  "payments": [
    {
      "status": "PENDING",
      "paymentAmount": 100,
      "paymentDate": "2020-02-01"
    },
    {
      "status": "PENDING",
      "paymentAmount": 100,
      "paymentDate": "2020-03-01"
    },
    {
      "status": "PENDING",
      "paymentAmount": 100,
      "paymentDate": "2020-04-01"
    },
    {
      "status": "PENDING",
      "paymentAmount": 100,
      "paymentDate": "2020-05-01"
    },
    {
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-06-01"
    }
  ]
}
Attribute Description
owedAmount
Numeric11
Required
The original amount, or the amount owed by the debtor.
settingId
Numeric 8
Required
The id of the ScheduleSetting to be used to generate the schedule preview.
initialPaymentAmount
Numeric11
Conditional
An amount processed before the schedule is started. This will be deducted from the owedAmount. If processInitialPaymentOnActivation is true this amount is required and will be processed. Otherwise this amount will not be processed, and is on the schedule for reference only.
adjustmentAmount
Numeric11
An amount to be deducted from the owedAmount. This amount will not be processed by the schedule, but is on the schedule for reference only.
numberOfPayments
Numeric3
The number of payments desired for the schedule. If this is provided the paymentAmount cannot be provided. If the number of payments requested is too great, causing each payment to be less than the minimumPaymentAmount specified in the ScheduleSetting, an error message will be provided that indicates the maximum number of payments.
paymentAmount
Numeric11
This is the amount that will be charged for each scheduled payment. If this is provided the numberOfPayments cannot be provided. If the payment amount is too small, causing the schedule length to exceed the termMonth for this amount, an error message will be provided that indicates the minimum value.
recurrenceRule
Alphanumeric255
This is the recurrence rule that you want the schedule to calculate the payments against. Passing in a recurrence rule here will override the recurrence that was saved as part of the ScheduleSetting referenced by the settingId. This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. Restrictions on which frequencies are allowed are stored in the ScheduleSetting object. There is no need to start a rule with “RRULE=”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31. Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”.

Schedule

POST to create a new schedule.
PUT to modify an existing schedule. This will ALWAYS regenerate the payment list based on the updated request parameters. All original values will be overwritten with the updated parameters.
PATCH to modify an existing schedule. This will NEVER regenerate the payment list and will only modify specified parameters. Passing in an empty value for a parameter will remove the stored value for that parameter.
DELETE to delete an existing schedule. Schedules with a payment that has been attempted, either successful or failed, cannot be deleted.
GET to get a list of schedules. The READONLY fields will only be present on this endpoint.

Schedule Object

Complete Schedule Object

Schedule Object:

{
  "id": 9107,
  "companyId": 1234,
  "status": "ACTIVE",
  "settingId": 2,
  "paymentMethod": "CARD",
  "requestPaymentData": false,
  "firstName": "Test",
  "lastName": "McTester",
  "accountNumber": "4654",
  "numberOfPayments": 4,
  "paymentAmount": 100.00,
  "memo": "I am making a schedule",
  "emailAddress": "test@test.com",
  "sendReceiptToEmailAddress": true,
  "phoneNumber": "1234567890",
  "sendAuthorizationRequest": true,
  "processInitialPaymentOnActivation": false,
  "authorization": {
    "pinDescription": "Last four of card number",
    "verificationPin": "1234",
    "timeoutMinutes": 30,
    "eventRecipientList": [
        {
            "emailAddress": "someone@example.com"
        }
    ]
  },
  "flowId": 2,
  "addressOne": "234 Test Street",
  "addressTwo": "Suite 3",
  "city": "Ogden",
  "state": "UT",
  "zip": "84401",
  "zipPlusFour": "1234",
  "country": "US",
  "origin": "EXT",
  "locationId": "12",
  "recurrenceRule": "FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1",
  "username": "testUser",
  "createUser": "testUser",
  "updateUser": "testUser",
  "createDate": "2012-06-26 12:10:55",
  "updateDate": "2014-01-16 10:19:45",
  "owedAmount": 900,
  "initialPaymentAmount": 500,
  "adjustmentAmount": 100,
  "pendingAmount": 100.00,
  "nextPaymentAmount": 100,
  "collectedAmount": 200.00,
  "unsuccessfulAmount": 100.00,
  "totalExpectedAmount": 300.00,
  "nextPaymentDate": "2014-01-24",
  "pendingCount": 1,
  "collectedCount": 2,
  "unsuccessfulCount": 1,
  "totalExpectedCount": 4,
  "billingLastFour": "2224",
  "billingCard": {
      "cardToken": "aCardToken123456",
      "expirationMonth": 4,
      "expirationYear": 16,
      "accountDirective": "888-1"
  },
  "billingCheck": {
      "bankAccountNumber": "aBankToken123456",
      "routingNumber": "123456789",
      "bankAccountType": "CHECKING", 
      "accountDirective": "123-1"
  },
  "payments": [
    {
      "paymentId": 33,
      "status": "PAID",
      "paymentAmount": 100.00,
      "paymentDate": "2012-11-22",
      "arrivalId": 43,
      "transactionId": 12345,
      "paymentAttempts": [
        {
          "arrivalId": 43,
          "transactionId": 12345,
          "attemptDate": "2019-11-22T11:00:46.000+0000",
          "status": "PAID"
        }
      ]
    },
    {
      "paymentId": 90739,
      "status": "PAID",
      "paymentAmount": 100.00,
      "paymentDate": "2013-02-17",
      "arrivalId": 44,
      "transactionId": 12346,
      "paymentAttempts": [
        {
          "arrivalId": 44,
          "transactionId": 12346,
          "attemptDate": "2013-02-17T11:00:46.000+0000",
          "status": "PAID"
        }
      ]
    },
    {
      "paymentId": 90740,
      "status": "FAILED",
      "paymentAmount": 100.00,
      "paymentDate": "2014-01-17",
      "arrivalId": 45,
      "transactionId": 12347,
      "paymentAttempts": [
        {
          "arrivalId": 45,
          "transactionId": 12347,
          "attemptDate": "2014-01-17T11:00:46.000+0000",
          "status": "FAILED",
          "statusMessage": "Insufficient Funds"
        }
      ]
    },
    {
      "paymentId": 90741,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2014-04-24"
    }
  ],
  "customReceiptLabels": {
    "PAYMENT": "My new payment label",
    "ACCOUNT_NUMBER": "My new account number label",
    "MEMO": "My new memo label",
    "BANK_ACCOUNT_TYPE": "My new account type label"
  },
  "customRenderLabels": {
    "SCHEDULE_STATUS": "My new schedule status label"
  },
  "roundTripMap": {
    "myField1": "Custom Value 1",
    "myField2": "Custom Value 2"
  },
  "scheduleHistoryList": [
      {
          "date": "2019-11-22 11:00:46",
          "event": "PAYMENT_ATTEMPT",
          "user": "recurring"
      },
      {
          "date": "2013-02-17 11:00:46",
          "event": "PAYMENT_ATTEMPT",
          "user": "recurring"
      },
      {
          "date": "2014-01-17 11:00:46",
          "event": "PAYMENT_ATTEMPT",
          "user": "recurring"
      }
  ]
}

Attribute Description
scheduleId
Numeric10
READONLY
The id of the schedule. This can be used to retrieve the schedule by sending an HTTP GET request with this id in the url.
companyId
Numeric8
READONLY
The companyId for which the schedule was created.
status
AlphaN/A
Valid value(s):
DRAFT - Schedule is not yet active. Use this to save an incomplete schedule to be returned to later.
ACTIVE - Schedule is active. Payments will be processed.
COMPLETED - Schedule is completed. All payments have been attempted, either successfully or unsuccessfully.
INACTIVE - Schedule is inactive. Payments will not be processed and any payments that are missed will be marked as SKIPPED and will not be processed if the schedule is changed to ACTIVE.
Default value: DRAFT
settingId
Numeric 10
The id of the schedule setting to be used with this schedule.
paymentMethod
Alpha5
The payment method to be used for processing payments on this schedule.
Valid value(s):
CARD
CHECK
sendFlowRequest
Boolean
Flag to determine if Schedule Service should send the Flow request, or if it will be requested separately using the Signature Service API
The following 2 attributes sendAuthorizationRequest and requestPaymentData still need to be set to the proper value so the Signature Service API can build the Flow request correctly.
Default value: true
sendAuthorizationRequest
Boolean5
Whether an authorization request will be sent to the included emailAddress and/or phoneNumber.
Default: false.
An authorization request will only be sent if the status of the schedule is ACTIVE, AUTHORIZE or UNAUTHORIZED. When an authorization request is sent, the schedule will be set to a status of AUTHORIZE until the account holder has completed the authorization request. When the authorization request is successfully completed, the status of the schedule will be set to ACTIVE.
requestPaymentData
Boolean5
If this is true, a flow request will be sent to the emailAddress or phoneNumber requesting the payment information.
processInitialPaymentOnActivation
Boolean5
If this is true, the initialPaymentAmount is required and will be processed when the schedule goes ACTIVE.
NOTE: When the payment is processed this value will be cleared.
firstName
Alphanumeric45
The first name of the person associated to this schedule.
lastName
Alphanumeric45
The last name of the person associated to this schedule.
accountNumber
Alphanumeric45
The accountNumber of the person associated to this schedule.
numberOfPayments
Numeric3
The number of payments used for creation of the schedule. If this is provided, the paymentAmount cannot be provided.
The number of payments, along with the minimum amount per payment, must generate a schedule with less payments than the maxTerm in the setting for this schedule. If the number of payments is too great, an error message will be provided that indicates the maximum value.
If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
paymentAmount
Numeric11
This is the amount that will be charged for each scheduled payment. If this is provided the numberOfPayments cannot be provided.
The paymentAmount, along with the term setting, must generate a schedule with less payments than the maxTerm in the setting for this schedule. If the payment amount is too small an error message will be provided that indicates the minimum value.
If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
memo
Alphanumeric50
The memo associated to the schedule.
emailAddress
Alphanumeric75
An email address to associate with the schedule. Reminders will be sent to this email address prior to payments being processed, according to the cardReminderDays or checkReminderDays in the Setting for this schedule.
If sendAuthorizationRequest is true, the flow request will be sent to this email address.
If requestPaymentData is true, the flow request will be sent to this email address.
sendReceiptToEmailAddress
Boolean5
Toggle the sending of email receipts on payment processing.
phoneNumber
Numeric10
A phone number to associate with the schedule.
If sendAuthorizationRequest is true, the flow request will be sent to this phone number via text message.
If requestPaymentData is true, the flow request will be sent to this phone number via text message.
sendAuthorizationRequest
BooleanN/A
Whether an authorization request will be sent to the included emailAddress and/or phoneNumber.
Default: false.
An authorization request will only be sent if the status of the schedule is ACTIVE, AUTHORIZE or UNAUTHORIZED. When an authorization request is sent, the schedule will be set to a status of AUTHORIZE until the account holder has completed the authorization request. When the authorization request is successfully completed, the status of the schedule will be set to ACTIVE.
authorization
AuthorizationN/A
The data relating to an authorization request.
flowId
Numeric20
READONLY
The id of the last flow request associated with this schedule. This will only be present if sendAuthorizationRequest or requestPaymentData is true.
addressOne
Alphanumeric80
The address for the person associated with this schedule.
addressTwo
Alphanumeric45
The second part of the address for the person associated with this schedule.
city
Alphanumeric45
The city for the person associated with this schedule.
state
Alphanumeric2
The state for the person associated with this schedule.
zip
Alphanumeric5
The zip code for the person associated with this schedule.
zipPlusFour
Alphanumeric4
The four digit zip code extension for the person associated with this schedule.
country
Alphanumeric2
The country for the person associated with this schedule.
origin
Alpha3
The origin of this schedule. This should always be set to “EXT”.
locationId
Numeric10
The locationId for a branch of the company setting up the schedule (if configured, typically this will be blank).
recurrenceRule
Alphanumeric255
This is the recurrence rule that you want the schedule to calculate the payments against. Passing in a recurrence rule here will override the recurrence that was saved as part of the Setting referenced by the settingId. This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. Restrictions on which frequencies are allowed are stored in the Setting object. There is no need to start a rule with “RRULE=”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31. Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”. If this is changed during a PUT call, then the SchedulePayments will be regenerated.
username
Alphanumeric75
The username for the employee creating the schedule. This value is used as the createUser and/or updateUser.
createUser
Alphanumeric75
READONLY
The user who created the Schedule.
updateUser
Alphanumeric75
READONLY
The user who last modified the Schedule.
createDate
Date19
READONLY
Date the Schedule was created.
Format: URL Encoded ISO-8601
updateDate
Date19
READONLY
Date the Schedule was last updated.
Format: URL Encoded ISO-8601
owedAmount
Numeric11
The original amount, or the amount owed by the debtor. If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
initialPaymentAmount
Numeric11
Conditional
An amount processed before the schedule is started. This will be deducted from the owedAmount.
If processInitialPaymentOnActivation is true this amount is required and will be processed. Otherwise this amount will not be processed, and is on the schedule for reference only.
Only returns if not zero on POST or PUT requests.
adjustmentAmount
Numeric11
An amount to be deducted from the owedAmount.
This amount will not be processed by the schedule, but is on the schedule for reference only.
Only returns if not zero on POST or PUT requests.
pendingAmount
Numeric11
READONLY
The total amount still pending on the schedule.
nextPaymentAmount
Numeric11
READONLY
The payment amount of the next scheduled payment.
collectedAmount
Numeric11
READONLY
The total amount that has been collected on the schedule.
unsuccessfulAmount
Numeric11
READONLY
The sum of the payment amounts of all failed payments on the schedule.
totalExpectedAmount
Numeric11
READONLY
The total amount of all payments on the schedule regardless of status, failed, successful or pending.
nextPaymentDate
DateTime19
READONLY
Date the next payment on the schedule is scheduled to process.
Format: URL Encoded ISO-8601
pendingCount
Numeric3
READONLY
The total number of payments that are still waiting to be collected on the schedule.
collectedCount
Numeric3
READONLY
The total number of payments that have been collected successfully on the schedule.
unsuccessfulCount
Numeric3
READONLY
The total number of payments that have been unsuccessful on the schedule.
totalExpectedCount
Numeric3
READONLY
The total number of payments associated with the schedule, regardless of current status.
billingLastFour
Alphanumeric 4
READONLY
The last four digits of the credit card number or the bank account number. From the active payment method.
billingCard
Object N/A
BillingCard object. This is ONLY returned when paymentMethod is CARD and when a single Schedule object is returned.
Description: See object definition below.
billingCheck
ObjectN/A
BillingCheck object. This is ONLY returned when paymentMethod is CHECK and when a single Schedule object is returned.
Description: See object definition below.
payments
ListN/A
List of SchedulePayment objects for the schedule. This will be returned when a single schedule is returned and cannot be modified through the schedules endpoint.
Description: See object definition below.
customReceiptLabels
ObjectN/A
CustomReceiptLabels object that contains labels which will override the default labels used on receipts. This will be returned when a single schedule is returned and can be modified through the schedules endpoint. Invalid values will be ignored.
Description: See object definition below.
customRenderLabels
ObjectN/A
customRenderLabels object that contains labels which will override the default labels used on a Schedule render. This will be returned when a single schedule is returned and can be modified through the schedules endpoint. Invalid values will be ignored.
Description: See object definition below.
roundTripMap
ObjectN/A
An object with a custom set of key/value pairs to save and return with the Schedule.
Both the Key and Value are required and must be 75 characters or less.
notificationEvent
String15
Specify if a Notification Event should be sent when the Schedule is created.
If this field is not provided, no Notification Event will be sent. This field is not saved and will not be returned on a GET
Valid value(s):
SCHEDULE
flowRequestList
ListN/A
READONLY
List of FlowRequest objects for the schedule. This will be returned when a single Schedule is returned and cannot be modified through the schedules endpoint. A flow request will be generated any time sendAuthorizationRequest or requestPaymentData is true.
Description: See object definition below.
scheduleHistoryList
ListN/A
READONLY
List of ScheduleHistory objects. This will be returned when a single Schedule is returned and cannot be modified through the schedules endpoint.
Description: See object definition below.

–Schedule Creation

POST :
test urls:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules
live urls:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules


Sample Response:

{
    "id": 2,
    "companyId": 1234,
    "accountNumber": "123455",
    "status": "AUTHORIZE",
    "paymentMethod": "CHECK",
    "firstName": "Test",
    "lastName": "McTester",
    "settingId": 1,
    "emailAddress": "test@test.com",
    "sendReceiptToEmailAddress": false,
    "origin": "EXT",
    "recurrenceRule": "FREQ=MONTHLY;INTERVAL=1;",
    "createUser": "testUser",
    "updateUser": "testUser",
    "createDate": "2020-01-02 16:40:21",
    "updateDate": "2020-01-02 16:40:21",
    "requestPaymentData": false,
    "sendAuthorizationRequest": true,
    "processInitialPaymentOnActivation": false,
    "flowId": 1,
    "pendingAmount": 1000.00,
    "nextPaymentAmount": 100.00,
    "collectedAmount": 0.00,
    "unsuccessfulAmount": 0.00,
    "totalExpectedAmount": 1000.00,
    "nextPaymentDate": "2020-01-13",
    "pendingCount": 10,
    "collectedCount": 0,
    "unsuccessfulCount": 0,
    "totalExpectedCount": 10,
    "owedAmount": 1000,
    "paymentAmount": 100,
    "billingLastFour": "4321",
    "billingCheck": {
        "bankAccountNumber": "aBankToken123456",
        "routingNumber": "123456789",
        "bankAccountType": "CHECKING",
        "accountDirective": "1271-1"
    },
    "payments": [
        {
            "paymentId": 2,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-01-13"
        },
        {
            "paymentId": 3,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-02-13"
        },
        {
            "paymentId": 4,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-03-13"
        },
        {
            "paymentId": 5,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-04-13"
        },
        {
            "paymentId": 6,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-05-13"
        },
        {
            "paymentId": 7,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-06-13"
        },
        {
            "paymentId": 8,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-07-13"
        },
        {
            "paymentId": 9,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-08-13"
        },
        {
            "paymentId": 10,
            "status": "PENDING",
            "paymentAmount": 100,
            "paymentDate": "2020-09-13"
        },
        {
            "paymentId": 11,
            "status": "PENDING",
            "paymentAmount": 100.00,
            "paymentDate": "2020-10-13"
        }
    ],
    "flowRequestList": [
        {
            "flowId": 2,
            "status": "PENDING",
            "statusDate": "2020-01-02 16:40:22"
        }
    ],
    "scheduleHistoryList": [
        {
            "date": "2020-01-02 16:40:21",
            "event": "CREATE",
            "eventId": 14,
            "user": "testUser"
        },
        {
            "date": "2020-01-02 16:40:22",
            "event": "AUTHORIZATION_REQUEST",
            "eventId": 15,
            "user": "testUser",
            "data": "Authorization request HTTP response status: 200 OK"
        },
        {
            "date": "2020-01-02 16:40:22",
            "event": "SCHEDULE_STATUS",
            "eventId": 16,
            "user": "testUser",
            "data": "Status: {ACTIVE} -> {AUTHORIZE}"
        }
    ]
}
Attribute Description
owedAmount
Numeric11
Required
The original amount, or the amount owed by the debtor. If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
initialPaymentAmount
Numeric11
Conditional
An amount processed before the schedule is started. This will be deducted from the owedAmount. If processInitialPaymentOnActivation is true this amount is required and will be processed. Otherwise this amount will not be processed, and is on the schedule for reference only.
Only returns if not zero on POST or PUT requests.
adjustmentAmount
Numeric11
An amount to be deducted from the owedAmount. This amount will not be processed by the schedule, but is on the schedule for reference only.
Only returns if not zero on POST or PUT requests.
status
AlphaN/A
Valid value(s):
DRAFT - Schedule is not yet active. Use this to save an incomplete schedule to be returned to later.
ACTIVE - Schedule is active. Payments will be processed.
COMPLETED - Schedule is completed. All payments have been attempted, either successfully or unsuccessfully.
INACTIVE - Schedule is inactive. Payments will not be processed and any payments that are missed will be marked as SKIPPED and will not be processed if the schedule is changed to ACTIVE.
Default value: DRAFT
settingId
Numeric 10
Required
The id of the schedule setting to be used with this schedule. The setting must first be saved.
sendFlowRequest
Boolean
Flag to determine if Schedule Service should send the Flow request, or if it will be requested separately using the Signature Service API
The following 2 attributes sendAuthorizationRequest and requestPaymentData still need to be set to the proper value so the Signature Service API can build the Flow request correctly.
Default value: true
sendAuthorizationRequest
Boolean5
Whether an authorization request will be sent to the included emailAddress and/or phoneNumber.
Default: false.
An authorization request will only be sent if the status of the schedule is ACTIVE, AUTHORIZE or UNAUTHORIZED. When an authorization request is sent, the schedule will be set to a status of AUTHORIZE until the account holder has completed the authorization request. When the authorization request is successfully completed, the status of the schedule will be set to ACTIVE.
If sendAuthorizationRequest is true, the Authorization object is required, along with either the emailAddress or phoneNumber.
requestPaymentData
Boolean5
If this is true, a flow request will be sent to the emailAddress or phoneNumber requesting the payment information.
The accountDirective for all allowed payment types is required if this is set to true.
A valid emailAddress or phoneNumber is required when set to true.
processInitialPaymentOnActivation
Boolean5
If this is true, the initialPaymentAmount is required and will be processed when the schedule goes ACTIVE.
NOTE: When the payment is processed this value will be cleared.
paymentMethod
Alpha5
Conditional
The payment method to be used for processing payments on this schedule.
Valid value(s):
CARD
CHECK
Required if requestPaymentData is false.
billingCard
ObjectN/A
Conditional
BillingCard object. This is ONLY returned when paymentMethod is CARD and when a single Schedule object is returned.
Required if paymentMethod is set to CARD. Only the accountDirective field in the billingCard object is required if requestPaymentData is true and CARD is an accepted payment type.
Details
cardToken
Alphanumeric 16
Required
The credit card token. This must be a token, and not a raw credit card number.
To create a token, see Secure Overlay API and/or TokenizationService.
expirationMonth
Numeric 2
Conditional
The credit card expiration month.
This value will be retrieved from the cardToken if not provided. Required if expirationYear is provided.
expirationYear
Numeric 2
Conditional
The credit card expiration year.
This value will be retrieved from the cardToken if not provided. Required if expirationMonth is provided.
accountDirective
Alphanumeric 10
Required
The account directive that defines which card merchant account to use for processing the schedule payments.
billingCheck
ObjectN/A
Conditional
BillingCheck object. This is ONLY returned when paymentMethod is CHECK and when a single Schedule object is returned.
Required if paymentMethod is set to CHECK. Only the accountDirective field in the billingCheck object is required if requestPaymentData is true and CHECK is an accepted payment type.
Details
routingNumber
Numeric 9
Conditional
The bank routing number for processing the schedule payments.
Required if a raw bankAccountNumber is provided. Otherwise it is retrieved from a token bankAccountNumber if not provided.
bankAccountNumber
Alphanumeric 20
Required
A bank Token or a raw bank account number to use for processing the schedule payments.
To create a token, see Secure Overlay API and/or TokenizationService.
NOTE: Providing a raw bank account number is deprecated. When a raw bank account number is provided, the bankAccountNumber, routingNumber, and bankAccountType will be Tokenized and the Token will be returned here as the bankAccountNumber
bankAccountType
AlphaN/A
Conditional
Valid values:
CHECKING
SAVINGS
Required if a raw bankAccountNumber is provided. Otherwise it is retrieved from a token bankAccountNumber if not provided.
accountDirective
Alphanumeric 10
Required
The account directive that defines which check merchant account to use for processing the schedule payments.
firstName
Alphanumeric45
Required
The first name of the person associated to this schedule.
lastName
Alphanumeric45
Required
The last name of the person associated to this schedule.
accountNumber
Alphanumeric45
Required
The accountNumber of the person associated to this schedule.
numberOfPayments
Numeric3
The number of payments used for creation of the schedule. If this is provided, the paymentAmount cannot be provided.
The number of payments, along with the minimum amount per payment, must generate a schedule with less payments than the maxTerm in the setting for this schedule. If the number of payments is too great, an error message will be provided that indicates the maximum value.
If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
paymentAmount
Numeric11
This is the amount that will be charged for each scheduled payment. If this is provided the numberOfPayments cannot be provided.
The paymentAmount, along with the term setting, must generate a schedule with less payments than the maxTerm in the setting for this schedule. If the payment amount is too small an error message will be provided that indicates the minimum value.
If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
memo
Alphanumeric50
The memo associated to the schedule.
sendReceiptToEmailAddress
Boolean5
Required
Toggle the sending of email receipts on payment processing. A valid emailAddress is required when set to true.
sendAuthorizationRequest
BooleanN/A
Whether an authorization request will be sent to the included emailAddress and/or phoneNumber.
Default: false.
An authorization request will only be sent if the status of the schedule is ACTIVE, AUTHORIZE or UNAUTHORIZED. When an authorization request is sent, the schedule will be set to a status of AUTHORIZE until the account holder has completed the authorization request. When the authorization request is successfully completed, the status of the schedule will be set to ACTIVE.
If sendAuthorizationRequest is true, the Authorization object is required, along with either the emailAddress or phoneNumber.
emailAddress
Alphanumeric75
Conditional
An email address to associate with the schedule. Reminders will be sent to this email address prior to payments being processed, according to the cardReminderDays or checkReminderDays in the Setting for this schedule.
If sendAuthorizationRequest is true, the flow request will be sent to this email address.
If requestPaymentData is true, the flow request will be sent to this email address.
Either the emailAddress or phoneNumber is required if sendAuthorizationRequest or requestPaymentData is true.
phoneNumber
Numeric10
Conditional
A phone number to associate with the schedule.
If sendAuthorizationRequest is true, the flow request will be sent to this phone number via text message.
If requestPaymentData is true, the flow request will be sent to this phone number via text message.
Either the emailAddress or phoneNumber is required if sendAuthorizationRequest or requestPaymentData is true.
authorization
AuthorizationN/A
Conditional
The data relating to an authorization request. Required if sendAuthorizationRequest or requestPaymentData is true.
Details
pinDescription
Alphanumeric50
Required
A description of the PIN the user will enter to access their authorization request. This cannot contain the verificationPin.
verificationPin
Numeric4-8
Required
The pin that the user will need to enter in order to access their authorization request.
verificationPageHeader
Alpha160
Text that will be displayed above the verification pin entry on the verification page.
pageFooter
Alpha1000
Text that will be displayed below the verification pin hint on the verification page.
timeoutMinutes
Numeric6
Required
The amount of minutes that the authorization request will be accessible for. The user must complete the authorization request before this timeout, or a new authorization request will need to be sent.
eventRecipientList
ListN/A
List of EventRecipient objects. These recipients will receive a notification for a final Flow status of COMPLETED, DISPUTED, EXPIRED, FAILED.
EventRecipient Object
emailAddress
Alphanumeric75
Required
An Email address to receive a Flow event notification.
addressOne
Alphanumeric80
The address for the person associated with this schedule.
addressTwo
Alphanumeric45
The second part of the address for the person associated with this schedule.
city
Alphanumeric45
The city for the person associated with this schedule.
state
Alphanumeric2
The state for the person associated with this schedule.
zip
Alphanumeric5
The zip code for the person associated with this schedule.
zipPlusFour
Alphanumeric4
The four digit zip code extension for the person associated with this schedule.
country
Alphanumeric2
The country for the person associated with this schedule.
origin
Alpha3
The origin of this schedule. This should always be set to “EXT”.
locationId
Numeric10
The locationId for a branch of the company setting up the schedule (if configured, typically this will be blank).
recurrenceRule
Alphanumeric255
This is the recurrence rule that you want the schedule to calculate the payments against. Passing in a recurrence rule here will override the recurrence that was saved as part of the Setting referenced by the settingId. This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. Restrictions on which frequencies are allowed are stored in the Setting object. There is no need to start a rule with “RRULE=”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31. Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”. If this is changed during a PUT call, then the SchedulePayments will be regenerated.
username
Alphanumeric75
Required
The username for the employee creating the schedule. This value is used as the createUser and/or updateUser.
customReceiptLabels
ObjectN/A
CustomReceiptLabels object that contains labels which will override the default labels used on receipts. This will be returned when a single schedule is returned and can be modified through the schedules endpoint. Invalid values will be ignored.
Description: See object definition below.
customRenderLabels
ObjectN/A
customRenderLabels object that contains labels which will override the default labels used on a Schedule render. This will be returned when a single schedule is returned and can be modified through the schedules endpoint. Invalid values will be ignored.
Description: See object definition below.
roundTripMap
ObjectN/A
An object with a custom set of key/value pairs to save and return with the Schedule.
Both the Key and Value are required and must be 75 characters or less.
notificationEvent
String15
Specify if a Notification Event should be sent when the Schedule is created.
If this field is not provided, no Notification Event will be sent. This field is not saved and will not be returned on a GET
Valid value(s):
SCHEDULE

–Schedule Override

PUT :
test urls:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}
live urls:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}


Sample Response:

{
  "id": 17381,
  "companyId": 1234,
  "accountNumber": "123455",
  "status": "ACTIVE",
  "paymentMethod": "CHECK",
  "firstName": "Test",
  "lastName": "McTester",
  "settingId": 5669,
  "emailAddress": "test@test.com",
  "sendReceiptToEmailAddress": false,
  "origin": "EXT",
  "recurrenceRule": "FREQ=MONTHLY;INTERVAL=1;",
  "createUser": "test@test.com",
  "updateUser": "testUser",
  "createDate": "2019-12-06 11:23:13",
  "updateDate": "2020-01-13 13:59:05",
  "requestPaymentData": false,
  "sendAuthorizationRequest": false,
  "processInitialPaymentOnActivation": false,
  "flowId": 3,
  "pendingAmount": 1000.00,
  "nextPaymentAmount": 100.00,
  "collectedAmount": 0.00,
  "unsuccessfulAmount": 0.00,
  "totalExpectedAmount": 1000.00,
  "nextPaymentDate": "2020-01-24",
  "pendingCount": 10,
  "collectedCount": 0,
  "unsuccessfulCount": 0,
  "totalExpectedCount": 10,
  "billingLastFour": "4321",
  "billingCheck": {
    "bankAccountNumber": "aBankToken123456",
    "routingNumber": "123456789",
    "bankAccountType": "CHECKING",
    "accountDirective": "1271-1"
  },
  "payments": [
    {
      "paymentId": 179361,
      "status": "PAID",
      "paymentAmount": 100.00,
      "paymentDate": "2019-12-07"
    },
    {
      "paymentId": 179362,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-02-24"
    },
    {
      "paymentId": 179363,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-03-24"
    },
    {
      "paymentId": 179364,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-04-24"
    },
    {
      "paymentId": 179365,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-05-24"
    },
    {
      "paymentId": 179366,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-06-24"
    },
    {
      "paymentId": 179367,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-07-24"
    },
    {
      "paymentId": 179368,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-08-24"
    },
    {
      "paymentId": 179369,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-09-24"
    },
    {
      "paymentId": 179370,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-10-24"
    }
  ],
  "customReceiptLabels": {
    "PAYMENT": "My new payment label",
    "ACCOUNT_NUMBER": "My new account number label",
    "MEMO": "My new memo label",
    "BANK_ACCOUNT_TYPE": "My new account type label"
  },
  "customRenderLabels": {
    "SCHEDULE_STATUS": "My new schedule status label"
  },
  "roundTripMap": {
    "myField1": "Custom Value 1",
    "myField2": "Custom Value 2"
  },
  "flowRequestList": [
    {
      "flowId": 29094,
      "status": "COMPLETED",
      "statusDate": "2019-12-06 11:23:47",
      "flowResultList": [
        {
          "flowId": 29094,
          "status": "BILLING_RECEIVE",
          "statusDate": "2019-12-06 11:23:47"
        },
        {
          "flowId": 29094,
          "status": "COMPLETED",
          "statusDate": "2019-12-06 11:23:47"
        }
      ]
    }
  ],
  "scheduleHistoryList": [
    {
      "date": "2019-12-06 11:23:13",
      "event": "CREATE",
      "eventId": 17381,
      "user": "test@test.com"
    },
    {
      "date": "2019-12-06 11:23:16",
      "event": "BILLING_REQUEST",
      "eventId": 29094,
      "user": "test@test.com",
      "data": "Authorization request HTTP response status: 200 OK"
    },
    {
      "date": "2019-12-06 11:23:17",
      "event": "SCHEDULE_STATUS",
      "eventId": 17381,
      "user": "test@test.com",
      "data": "Status: {ACTIVE} -> {BILLING_DATA}"
    },
    {
      "date": "2019-12-06 11:23:47",
      "event": "BILLING_MODIFY",
      "eventId": 17381,
      "user": "signatureUI",
      "data": "Change Billing Card"
    },
    {
      "date": "2019-12-06 11:23:47",
      "event": "FLOW_RESULT",
      "eventId": 3236,
      "user": "signatureUI",
      "data": "FlowId: 29094 Updated with status of BILLING_RECEIVE"
    },
    {
      "date": "2019-12-06 11:23:47",
      "event": "SCHEDULE_STATUS",
      "eventId": 17381,
      "user": "signatureUI",
      "data": "Status: {BILLING_DATA} -> {ACTIVE}"
    },
    {
      "date": "2019-12-06 11:23:47",
      "event": "FLOW_RESULT",
      "eventId": 3237,
      "user": "signatureUI",
      "data": "FlowId: 29094 Updated with status of COMPLETED"
    },
    {
      "date": "2019-12-07 04:00:50",
      "event": "PAYMENT_ATTEMPT",
      "eventId": 2229,
      "user": "recurring"
    },
    {
      "date": "2020-01-13 13:59:05",
      "event": "SCHEDULE_MODIFY",
      "eventId": 17381,
      "user": "testUser"
    }
  ]
}

PUT requests will completely override the existing specified (by scheduleId in the URL) schedule. As such, the request object the same as the schedule creation. Modifying a schedule will remove all PENDING payments from the existing schedule and will generate new payments based off the PUT request. Payments that have already been processed for this schedule will not be changed.

Schedule Modification
Attribute Description
scheduleId
Alpha8
The id of the Schedule to modify. Set in the URL.
status
AlphaN/A
Valid value(s):
DRAFT - Schedule is not yet active. Use this to save an incomplete schedule to be returned to later.
ACTIVE - Schedule is active. Payments will be processed.
COMPLETED - Schedule is completed. All payments have been attempted, either successfully or unsuccessfully.
INACTIVE - Schedule is inactive. Payments will not be processed and any payments that are missed will be marked as SKIPPED and will not be processed if the schedule is changed to ACTIVE.
settingId
Numeric 10
Required
The id of the schedule setting to be used with this schedule. The setting must first be saved.
paymentMethod
Alpha5
Conditional
The payment method to be used for processing payments on this schedule.
Valid value(s):
CARD
CHECK
Required if requestPaymentData is false.
requestPaymentData
Boolean5
If this is true, a flow request will be sent to the emailAddress or phoneNumber requesting the payment information.
The accountDirective for all allowed payment types is required if this is set to true.
A valid emailAddress or phoneNumber is required when set to true.
processInitialPaymentOnActivation
Boolean5
If this is true, the initialPaymentAmount is required and will be processed when the schedule goes ACTIVE.
NOTE: When the payment is processed this value will be cleared.
firstName
Alphanumeric45
Required
The first name of the person associated to this schedule.
lastName
Alphanumeric45
Required
The last name of the person associated to this schedule.
accountNumber
Alphanumeric45
Required
The accountNumber of the person associated to this schedule.
numberOfPayments
Numeric3
The number of payments used for creation of the schedule. If this is provided, the paymentAmount cannot be provided.
The number of payments, along with the minimum amount per payment, must generate a schedule with less payments than the maxTerm in the setting for this schedule. If the number of payments is too great, an error message will be provided that indicates the maximum value.
If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
paymentAmount
Numeric11
This is the amount that will be charged for each scheduled payment. If this is provided the numberOfPayments cannot be provided.
The paymentAmount, along with the term setting, must generate a schedule with less payments than the maxTerm in the setting for this schedule. If the payment amount is too small an error message will be provided that indicates the minimum value.
If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
memo
Alphanumeric50
The memo associated to the schedule.
emailAddress
Alphanumeric75
Conditional
An email address to associate with the schedule. Reminders will be sent to this email address prior to payments being processed, according to the cardReminderDays or checkReminderDays in the Setting for this schedule.
If sendAuthorizationRequest is true, the flow request will be sent to this email address.
If requestPaymentData is true, the flow request will be sent to this email address.
Either the emailAddress or phoneNumber is required if sendAuthorizationRequest or requestPaymentData is true.
sendReceiptToEmailAddress
Boolean5
Required
Toggle the sending of email receipts on payment processing. A valid emailAddress is required when set to true.
phoneNumber
Numeric10
Conditional
A phone number to associate with the schedule.
If sendAuthorizationRequest is true, the flow request will be sent to this phone number via text message.
If requestPaymentData is true, the flow request will be sent to this phone number via text message.
Either the emailAddress or phoneNumber is required if sendAuthorizationRequest or requestPaymentData is true.
sendAuthorizationRequest
BooleanN/A
Whether an authorization request will be sent to the included emailAddress and/or phoneNumber.
Default: false.
An authorization request will only be sent if the status of the schedule is ACTIVE, AUTHORIZE or UNAUTHORIZED. When an authorization request is sent, the schedule will be set to a status of AUTHORIZE until the account holder has completed the authorization request. When the authorization request is successfully completed, the status of the schedule will be set to ACTIVE.
If sendAuthorizationRequest is true, the Authorization object is required, along with either the emailAddress or phoneNumber.
authorization
AuthorizationN/A
Conditional
The data relating to an authorization request. Required if sendAuthorizationRequest or requestPaymentData is true.
Details
pinDescription
Alphanumeric50
Required
A description of the PIN the user will enter to access their authorization request. This cannot contain the verificationPin.
verificationPin
Numeric4-8
Required
The pin that the user will need to enter in order to access their authorization request.
timeoutMinutes
Numeric6
Required
The amount of minutes that the authorization request will be accessible for. The user must complete the authorization request before this timeout, or a new authorization request will need to be sent.
eventRecipientList
ListN/A
List of EventRecipient objects. These recipients will receive a notification for a final Flow status of COMPLETED, DISPUTED, EXPIRED, FAILED.
EventRecipient Object
emailAddress
Alphanumeric75
Required
An Email address to receive a Flow event notification.
addressOne
Alphanumeric80
The address for the person associated with this schedule.
addressTwo
Alphanumeric45
The second part of the address for the person associated with this schedule.
city
Alphanumeric45
The city for the person associated with this schedule.
state
Alphanumeric2
The state for the person associated with this schedule.
zip
Alphanumeric5
The zip code for the person associated with this schedule.
zipPlusFour
Alphanumeric4
The four digit zip code extension for the person associated with this schedule.
country
Alphanumeric2
The country for the person associated with this schedule.
origin
Alpha3
The origin of this schedule. This should always be set to “EXT”.
locationId
Numeric10
The locationId for a branch of the company setting up the schedule (if configured, typically this will be blank).
recurrenceRule
Alphanumeric255
This is the recurrence rule that you want the schedule to calculate the payments against. Passing in a recurrence rule here will override the recurrence that was saved as part of the Setting referenced by the settingId. This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. Restrictions on which frequencies are allowed are stored in the Setting object. There is no need to start a rule with “RRULE=”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31. Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”. If this is changed during a PUT call, then the SchedulePayments will be regenerated.
username
Alphanumeric75
Required
The username for the employee creating the schedule. This value is used as the createUser and/or updateUser.
owedAmount
Numeric11
Required
The original amount, or the amount owed by the debtor. If this is changed during a PUT call, then the SchedulePayments will be regenerated. Only returns if not zero on POST or PUT requests.
initialPaymentAmount
Numeric11
Conditional
An amount processed before the schedule is started. This will be deducted from the owedAmount.
If processInitialPaymentOnActivation is true this amount is required and will be processed. Otherwise this amount will not be processed, and is on the schedule for reference only.
Only returns if not zero on POST or PUT requests.
adjustmentAmount
Numeric11
An amount to be deducted from the owedAmount.
This amount will not be processed by the schedule, but is on the schedule for reference only.
Only returns if not zero on POST or PUT requests.
billingCard
Object
N/A
Conditional
BillingCard object. This is ONLY returned when paymentMethod is CARD and when a single Schedule object is returned.
Required if paymentMethod is set to CARD. Only the accountDirective field in the billingCard object is required if requestPaymentData is true and CARD is an accepted payment type.
Details
cardToken
Alphanumeric 16
Required
The credit card token. This must be a token, and not a raw credit card number.
To create a token, see Secure Overlay API and/or TokenizationService.
expirationMonth
Numeric 2
Conditional
The credit card expiration month.
This value will be retrieved from the cardToken if not provided. Required if expirationYear is provided.
expirationYear
Numeric 2
Conditional
The credit card expiration year.
This value will be retrieved from the cardToken if not provided. Required if expirationMonth is provided.
accountDirective
Alphanumeric 10
Required
The account directive that defines which card merchant account to use for processing the schedule payments.
billingCheck
Object
N/A
Conditional
BillingCheck object. This is ONLY returned when paymentMethod is CHECK and when a single Schedule object is returned.
Required if paymentMethod is set to CHECK. Only the accountDirective field in the billingCheck object is required if requestPaymentData is true and CHECK is an accepted payment type.
Details
routingNumber
Numeric 9
Conditional
The bank routing number for processing the schedule payments.
Required if a raw bankAccountNumber is provided. Otherwise it is retrieved from a token bankAccountNumber if not provided.
bankAccountNumber
Alphanumeric 20
Required
A bank Token or a raw bank account number to use for processing the schedule payments.
To create a token, see Secure Overlay API and/or TokenizationService.
NOTE: Providing a raw bank account number is deprecated. When a raw bank account number is provided, the bankAccountNumber, routingNumber, and bankAccountType will be Tokenized and the Token will be returned here as the bankAccountNumber
bankAccountType
AlphaN/A
Conditional
Valid values:
CHECKING
SAVINGS
Required if a raw bankAccountNumber is provided. Otherwise it is retrieved from a token bankAccountNumber if not provided.
accountDirective
Alphanumeric 10
Required
The account directive that defines which check merchant account to use for processing the schedule payments.
customReceiptLabels
ObjectN/A
CustomReceiptLabels object that contains labels which will override the default labels used on receipts. This will be returned when a single schedule returned and can be modified through the schedules endpoint. Invalid values will be ignored.
Description: See object definition below.
customRenderLabels
ObjectN/A
customRenderLabels object that contains labels which will override the default labels used on a Schedule render. This will be returned when a single schedule is returned and can be modified through the schedules endpoint. Invalid values will be ignored.
Description: See object definition below.
roundTripMap
ObjectN/A
An object with a custom set of key/value pairs to save and return with the Schedule.
Both the Key and Value are required and must be 75 characters or less.
notificationEvent
String15
Specify if a Notification Event should be sent when the Schedule is created.
If this field is not provided, no Notification Event will be sent. This field is not saved and will not be returned on a GET
Valid value(s):
SCHEDULE

–Schedule Modification

PATCH :
test urls:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}
live urls:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}


Sample Response:

{
  "id": 17381,
  "companyId": 1234,
  "accountNumber": "123455",
  "status": "ACTIVE",
  "paymentMethod": "CHECK",
  "firstName": "Test",
  "lastName": "McTester",
  "settingId": 5669,
  "emailAddress": "test@test.com",
  "sendReceiptToEmailAddress": false,
  "origin": "EXT",
  "recurrenceRule": "FREQ=MONTHLY;INTERVAL=1;",
  "createUser": "test@test.com",
  "updateUser": "testUser",
  "createDate": "2019-12-06 11:23:13",
  "updateDate": "2020-01-13 13:59:05",
  "requestPaymentData": false,
  "sendAuthorizationRequest": false,
  "flowId": 3,
  "pendingAmount": 1000.00,
  "nextPaymentAmount": 100.00,
  "collectedAmount": 0.00,
  "unsuccessfulAmount": 0.00,
  "totalExpectedAmount": 1000.00,
  "nextPaymentDate": "2020-01-24",
  "pendingCount": 10,
  "collectedCount": 0,
  "unsuccessfulCount": 0,
  "totalExpectedCount": 10,
  "billingLastFour": "4321",
  "billingCheck": {
    "bankAccountNumber": "aBankToken123456",
    "routingNumber": "123456789",
    "bankAccountType": "CHECKING",
    "accountDirective": "1271-1"
  },
  "payments": [
    {
      "paymentId": 179361,
      "status": "PAID",
      "paymentAmount": 100.00,
      "paymentDate": "2019-12-07"
    },
    {
      "paymentId": 179362,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-02-24"
    },
    {
      "paymentId": 179363,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-03-24"
    },
    {
      "paymentId": 179364,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-04-24"
    },
    {
      "paymentId": 179365,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-05-24"
    },
    {
      "paymentId": 179366,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-06-24"
    },
    {
      "paymentId": 179367,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-07-24"
    },
    {
      "paymentId": 179368,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-08-24"
    },
    {
      "paymentId": 179369,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-09-24"
    },
    {
      "paymentId": 179370,
      "status": "PENDING",
      "paymentAmount": 100.00,
      "paymentDate": "2020-10-24"
    }
  ],
  "customReceiptLabels": {
      "PAYMENT": "My new payment label",
      "ACCOUNT_NUMBER": "My new account number label",
      "MEMO": "My new memo label",
      "BANK_ACCOUNT_TYPE": "My new account type label"
  },
  "customRenderLabels": {
      "SCHEDULE_STATUS": "My new schedule status label"
  },
  "roundTripMap": {
    "myField1": "Custom Value 1",
    "myField2": "Custom Value 2"
  },
  "flowRequestList": [
    {
      "flowId": 29094,
      "status": "COMPLETED",
      "statusDate": "2019-12-06 11:23:47",
      "flowResultList": [
        {
          "flowId": 29094,
          "status": "BILLING_RECEIVE",
          "statusDate": "2019-12-06 11:23:47"
        },
        {
          "flowId": 29094,
          "status": "COMPLETED",
          "statusDate": "2019-12-06 11:23:47"
        }
      ]
    }
  ],
  "scheduleHistoryList": [
    {
      "date": "2019-12-06 11:23:13",
      "event": "CREATE",
      "eventId": 17381,
      "user": "test@test.com"
    },
    {
      "date": "2019-12-06 11:23:16",
      "event": "BILLING_REQUEST",
      "eventId": 29094,
      "user": "test@test.com",
      "data": "Authorization request HTTP response status: 200 OK"
    },
    {
      "date": "2019-12-06 11:23:17",
      "event": "SCHEDULE_STATUS",
      "eventId": 17381,
      "user": "test@test.com",
      "data": "Status: {ACTIVE} -> {BILLING_DATA}"
    },
    {
      "date": "2019-12-06 11:23:47",
      "event": "BILLING_MODIFY",
      "eventId": 17381,
      "user": "signatureUI",
      "data": "Change Billing Card"
    },
    {
      "date": "2019-12-06 11:23:47",
      "event": "FLOW_RESULT",
      "eventId": 3236,
      "user": "signatureUI",
      "data": "FlowId: 29094 Updated with status of BILLING_RECEIVE"
    },
    {
      "date": "2019-12-06 11:23:47",
      "event": "SCHEDULE_STATUS",
      "eventId": 17381,
      "user": "signatureUI",
      "data": "Status: {BILLING_DATA} -> {ACTIVE}"
    },
    {
      "date": "2019-12-06 11:23:47",
      "event": "FLOW_RESULT",
      "eventId": 3237,
      "user": "signatureUI",
      "data": "FlowId: 29094 Updated with status of COMPLETED"
    },
    {
      "date": "2019-12-07 04:00:50",
      "event": "PAYMENT_ATTEMPT",
      "eventId": 2229,
      "user": "recurring"
    },
    {
      "date": "2020-01-13 13:59:05",
      "event": "SCHEDULE_MODIFY",
      "eventId": 17381,
      "user": "testUser"
    }
  ]
}

PATCH requests will update the existing specified (by scheduleId in the URL) schedule. This is a soft update and will not regenerate the schedule payments. As such, fields which would require the payments to be regenerated will not be allowed in this request. Fields left null will not affect the schedule, while fields set to an empty string will remove the stored value from the schedule. As such, certain required fields cannot be set to empty.

Attribute Description
scheduleId
Alpha8
The id of the Schedule to modify. Set in the URL.
firstName
Alphanumeric45
Cannot be set empty. The first name of the person associated to this schedule.
lastName
Alphanumeric45
Cannot be set empty. The last name of the person associated to this schedule.
accountNumber
Alphanumeric45
Cannot be set empty. The accountNumber of the person associated to this schedule.
origin
Alpha3
The origin of this schedule. This should always be set to “EXT”.
status
AlphaN/A
Cannot be set empty.
Valid value(s):
DRAFT - Schedule is not yet active. Use this to save an incomplete schedule to be returned to later.
ACTIVE - Schedule is active. Payments will be processed.
COMPLETED - Schedule is completed. All payments have been attempted, either successfully or unsuccessfully.
INACTIVE - Schedule is inactive. Payments will not be processed and any payments that are missed will be marked as SKIPPED and will not be processed if the schedule is changed to ACTIVE.
paymentMethod
Alpha5
The payment method to be used for processing payments on this schedule.
Valid value(s):
CARD
CHECK
requestPaymentData
Boolean5
If this is true, a flow request will be sent to the emailAddress or phoneNumber requesting the payment information.
The accountDirective for all allowed payment types is required if this is set to true.
A valid emailAddress or phoneNumber is required when set to true.
memo
Alphanumeric50
The memo associated to the schedule.
emailAddress
Alphanumeric75
An email address to associate with the schedule. Reminders will be sent to this email address prior to payments being processed, according to the cardReminderDays or checkReminderDays in the Setting for this schedule.
If sendAuthorizationRequest is true, the flow request will be sent to this email address.
If requestPaymentData is true, the flow request will be sent to this email address.
Either the emailAddress or phoneNumber is required if sendAuthorizationRequest or requestPaymentData is true.
sendReceiptToEmailAddress
Boolean5
Toggle the sending of email receipts on payment processing. A valid emailAddress is required when set to true.
phoneNumber
Numeric10
A phone number to associate with the schedule.
If sendAuthorizationRequest is true, the flow request will be sent to this phone number via text message.
If requestPaymentData is true, the flow request will be sent to this phone number via text message.
Either the emailAddress or phoneNumber is required if sendAuthorizationRequest or requestPaymentData is true.
sendAuthorizationRequest
BooleanN/A
Whether an authorization request will be sent to the included emailAddress and/or phoneNumber.
Default: false.
An authorization request will only be sent if the status of the schedule is ACTIVE, AUTHORIZE or UNAUTHORIZED. When an authorization request is sent, the schedule will be set to a status of AUTHORIZE until the account holder has completed the authorization request. When the authorization request is successfully completed, the status of the schedule will be set to ACTIVE.
If sendAuthorizationRequest is true, the Authorization object is required, along with either the emailAddress or phoneNumber.
authorization
AuthorizationN/A
Conditional
The data relating to an authorization request. Required if sendAuthorizationRequest or requestPaymentData is true.
Details
pinDescription
Alphanumeric50
Required
A description of the PIN the user will enter to access their authorization request. This cannot contain the verificationPin.
verificationPin
Numeric4-8
Required
The pin that the user will need to enter in order to access their authorization request.
timeoutMinutes
Numeric6
Required
The amount of minutes that the authorization request will be accessible for. The user must complete the authorization request before this timeout, or a new authorization request will need to be sent.
eventRecipientList
ListN/A
List of EventRecipient objects. These recipients will receive a notification for a final Flow status of COMPLETED, DISPUTED, EXPIRED, FAILED.
EventRecipient Object
emailAddress
Alphanumeric75
Required
An Email address to receive a Flow event notification.
addressOne
Alphanumeric80
The address for the person associated with this schedule.
addressTwo
Alphanumeric45
The second part of the address for the person associated with this schedule.
city
Alphanumeric45
The city for the person associated with this schedule.
state
Alphanumeric2
The state for the person associated with this schedule.
zip
Alphanumeric5
The zip code for the person associated with this schedule.
zipPlusFour
Alphanumeric4
The four digit zip code extension for the person associated with this schedule.
country
Alphanumeric2
The country for the person associated with this schedule.
locationId
Numeric10
The locationId for a branch of the company setting up the schedule (if configured. Typically this will be blank).
username
Alphanumeric75
Required
The username for the employee creating the schedule. This value is used as the createUser and/or updateUser.
billingCard
ObjectN/A
Conditional
BillingCard object. This is ONLY returned when paymentMethod is CARD and when a single Schedule object is returned.
Required if paymentMethod is set to CARD. Only the accountDirective field in the billingCard object is required if requestPaymentData is true and CARD is an accepted payment type.
Details
cardToken
Alphanumeric 16
Required
The credit card token. This must be a token, and not a raw credit card number.
To create a token, see Secure Overlay API and/or TokenizationService.
expirationMonth
Numeric 2
Conditional
The credit card expiration month.
This value will be retrieved from the cardToken if not provided. Required if expirationYear is provided.
expirationYear
Numeric 2
Conditional
The credit card expiration year.
This value will be retrieved from the cardToken if not provided. Required if expirationMonth is provided.
accountDirective
Alphanumeric 10
Required
The account directive that defines which card merchant account to use for processing the schedule payments.
billingCheck
ObjectN/A
Conditional
BillingCheck object. This is ONLY returned when paymentMethod is CHECK and when a single Schedule object is returned.
Required if paymentMethod is set to CHECK. Only the accountDirective field in the billingCheck object is required if requestPaymentData is true and CHECK is an accepted payment type.
Details
routingNumber
Numeric 9
Conditional
The bank routing number for processing the schedule payments.
Required if a raw bankAccountNumber is provided. Otherwise it is retrieved from a token bankAccountNumber if not provided.
bankAccountNumber
Alphanumeric 20
Required
A bank Token or a raw bank account number to use for processing the schedule payments.
To create a token, see Secure Overlay API and/or TokenizationService.
NOTE: Providing a raw bank account number is deprecated. When a raw bank account number is provided, the bankAccountNumber, routingNumber, and bankAccountType will be Tokenized and the Token will be returned here as the bankAccountNumber
bankAccountType
AlphaN/A
Conditional
Valid values:
CHECKING
SAVINGS
Required if a raw bankAccountNumber is provided. Otherwise it is retrieved from a token bankAccountNumber if not provided.
accountDirective
Alphanumeric 10
Required
The account directive that defines which check merchant account to use for processing the schedule payments.
customReceiptLabels
ObjectN/A
CustomReceiptLabels object that contains labels which will override the default labels used on receipts. This will be returned when a single schedule returned and can be modified through the schedules endpoint. Invalid values will be ignored.
Description: See object definition below.
customRenderLabels
ObjectN/A
customRenderLabels object that contains labels which will override the default labels used on a Schedule render. This will be returned when a single schedule is returned and can be modified through the schedules endpoint. Invalid values will be ignored.
Description: See object definition below.
roundTripMap
ObjectN/A
An object with a custom set of key/value pairs to save and return with the Schedule.
Both the Key and Value are required and must be 75 characters or less.
notificationEvent
String15
Specify if a Notification Event should be sent when the Schedule is created.
If this field is not provided, no Notification Event will be sent. This field is not saved and will not be returned on a GET
Valid value(s):
SCHEDULE

–Account Directive Migration

PATCH :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/migrations/accountdirectives
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/migrations/accountdirectives

Sample Response:

{
  "response": "Account directive migration started for 15 schedules"
}

Send a PATCH request with a AccountDirectiveMigration body to migrate all schedules that aren’t in a COMPLETED status from one accountDirective to another. This will apply only to unprocessed new scheduled payments. Returns a MigrationResponse. This is an asynchronous process and realtime processing results will not be returned.

AccountDirectiveMigration

Attribute Description
oldAccountDirective
Alphanumeric String 10
Required
The accountDirective assigned to the targeted schedules.
newAccountDirective
Alphanumeric String 10
Required
The desired accountDirective to assign to the targeted schedules.
Constraint(s): Must be valid for the same payment method as the oldAccountDirective.
If the payment method is CARD, this field must allow at least the same card types as the oldAccountDirective.
If the payment method is CHECK, this field must be valid for the same SEC code as the oldAccountDirective

MigrationResponse

Attribute Description
response
String
A description of the processing status.
requestErrorList
List
A list of RequestError objects. Only returned on unsuccessful migrations.

–Schedule Retrieval (List)

POST :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/search
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/search


Sample Response:

{
  "scheduleList": [
    {
      "id": 23,
      "companyId": 1234,
      "accountNumber": "456465",
      "status": "COMPLETED",
      "paymentMethod": "CHECK",
      "firstName": "Cashier",
      "lastName": "test",
      "settingId": 2,
      "memo": "Cashier test",
      "addressOne": "3242 Street",
      "city": "myCity",
      "state": "UT",
      "zip": "12345",
      "origin": "EXT",
      "locationId": "2",
      "recurrenceRule": "FREQ=MONTHLY;INTERVAL=1;",
      "createUser": "test@test.com",
      "updateUser": "tester@test.com",
      "createDate": "2018-04-03 15:48:07",
      "updateDate": "2018-08-30 10:44:37",
      "requestPaymentData": false,
      "sendAuthorizationRequest": false,
      "pendingAmount": 0.00,
      "nextPaymentAmount": 0.00,
      "collectedAmount": 100.00,
      "unsuccessfulAmount": 400.00,
      "totalExpectedAmount": 580.00,
      "pendingCount": 0,
      "collectedCount": 4,
      "unsuccessfulCount": 1,
      "totalExpectedCount": 5,
      "initialPaymentAmount": 0,
      "adjustmentAmount": 0,
      "billingLastFour": "1212"
    },
    {
      "id": 24,
      "companyId": 1234,
      "accountNumber": "12344",
      "status": "COMPLETED",
      "paymentMethod": "CARD",
      "firstName": "Arthur",
      "lastName": "TestMan",
      "settingId": 3,
      "emailAddress": "tested@test.com",
      "origin": "EXT",
      "recurrenceRule": "FREQ=DAILY;INTERVAL=1;",
      "createUser": "test@test.com",
      "updateUser": "test@test.com",
      "createDate": "2018-04-05 12:17:28",
      "updateDate": "2018-04-26 17:15:55",
      "requestPaymentData": false,
      "sendAuthorizationRequest": false,
      "pendingAmount": 0.00,
      "collectedAmount": 10.01,
      "unsuccessfulAmount": 0.00,
      "totalExpectedAmount": 10.01,
      "pendingCount": 0,
      "collectedCount": 2,
      "unsuccessfulCount": 0,
      "totalExpectedCount": 2,
      "initialPaymentAmount": 0,
      "adjustmentAmount": 0,
      "billingLastFour": "2224"
    },
    {
      "id": 25,
      "companyId": 1234,
      "accountNumber": "8874",
      "status": "ACTIVE",
      "paymentMethod": "CARD",
      "firstName": "Keith",
      "lastName": "CardTester",
      "settingId": 1374,
      "emailAddress": "test@tests.com",
      "phoneNumber": "8017810199",
      "addressOne": "223 Round Ave",
      "city": "CityPlace",
      "state": "UT",
      "zip": "84421",
      "origin": "EXT",
      "locationId": "23",
      "recurrenceRule": "FREQ=MONTHLY;INTERVAL=1;",
      "createUser": "test@test.com",
      "updateUser": "test@test.com",
      "createDate": "2018-05-01 16:29:09",
      "updateDate": "2018-08-17 10:31:00",
      "requestPaymentData": false,
      "sendAuthorizationRequest": false,
      "pendingAmount": 28000.00,
      "nextPaymentAmount": 1000.00,
      "collectedAmount": 16080.00,
      "unsuccessfulAmount": 1005.00,
      "totalExpectedAmount": 45085.00,
      "nextPaymentDate": "2020-01-18",
      "pendingCount": 28,
      "collectedCount": 23,
      "unsuccessfulCount": 2,
      "totalExpectedCount": 53,
      "initialPaymentAmount": 0,
      "adjustmentAmount": 0,
      "billingLastFour": "1111"
    }
  ]
}

POST to retrieve a list of Schedule objects filtered on a SearchParameters object passed in.

SearchParameters

Attribute Description
createStartDate
DateTime19
Filters the records by looking for schedules with a createDate newer than or equal to the date provided. Formatted “yyyy-MM-dd HH:mm:ss”.
Format: URL Encoded ISO-8601
createEndDate
DateTime19
Filters the records by looking for schedules with a createDate older than or equal to the date provided. Formatted “yyyy-MM-dd HH:mm:ss”.
Format: URL Encoded ISO-8601
updateStartDate
DateTime19
Filters the records by looking for schedules with a updateDate newer than or equal to the date provided. Formatted “yyyy-MM-dd HH:mm:ss”.
Format: URL Encoded ISO-8601
updateEndDate
DateTime19
Filters the records by looking for schedules with a updateDate older than or equal to the date provided. Formatted “yyyy-MM-dd HH:mm:ss”.
Format: URL Encoded ISO-8601
firstName
Alphanumeric45
Filters the records by the first name on the schedule.
lastName
Alphanumeric45
Filters the records by the last name on the schedule.
accountNumber
45
Alphanumeric
Filters the records by the account number on the schedule.
paymentType
AlphanumericN/A
Filters the records by the payment type on the schedule. If empty then both values will be used.
Valid value(s):
CARD
CHECK
origin
ListN/A
Filter the records by a list of origins. You can pass in an alphanumeric list of Origin values.
createUser
Alphanumeric75
Deprecated
This field has been deprecated in favor of using createUserList
createUserList
ListN/A
Filters the records by a list of alphanumeric users who created the record. Users cannot be longer than 75 characters.
updateUser
Alphanumeric75
Deprecated
This field has been deprecated in favor of using updateUserList.
updateUserList
ListN/A
Filters the records by a list of alphanumeric users who have updated the record. Users cannot be longer than 75 characters.
billingLastFour
Alphanumeric4
Filters the records by the last four of the card number or bank account number.
status
ListN/A
Filters the records by the current status of the Schedule. You can pass in a list of values.
Valid value(s):
DRAFT - Schedules in DRAFT have not yet been saved as ACTIVE.
ACTIVE - Schedules that are actively processing payments.
INACTIVE - Schedules that have been inactivated and are no longer running payments, though PENDING payments may still be present.
COMPLETED - Schedules that have finished processing all payments, be they successful or failed.
AUTHORIZE - Schedules that are pending the completion of a signature request before becoming ACTIVE.
UNAUTHORIZED - Schedules of which the signature request was not completed successfully.
BILLING_DATA - Schedules that are pending the completion of a signature request requesting payment data to be entered.
accountDirectiveList
ListN/A
Filters the records by a list of their associated account directives.
locationIdList
ListN/A
Filters the records by a list of numeric locationIds.
To search for schedules that do not have a locationId assigned, include 0 as one of the locationId’s to search for.
roundTripMapSearch
ListN/A
Filters the records by a list of SearchRoundTripMap objects. Those key/value pairs combined as a single object will perform an AND search for Schedules matching all those of the single object. A separate object of key/value pairs will perform an OR search for Schedules matching any pairs between the separate objects in the list.
see search example
recordStart
Numeric20
The record count to start on.
Default: 0
recordCount
Numeric4
How many records to return.
Default: 2000
Maximum: 5000

SearchRoundTripMap

Attribute Description
YOUR_KEY_NAME
Alphanumeric75
Required
The round trip name to filter by.
YOUR_VALUES
Alphanumeric ListN/A
Required
A list of values for the round trip name to filter by.
If the list contains a value of -1, the results will also be filtered to include schedules that do not contain a RoundTripMap with the specified name
Constraint(s): Each value must not exceed 75 characters

Example roundTripMapSearch

WHERE
((“Key 1” == “Key 1 Value 1” OR “Key 1” == “Key 1 Value 2”) AND (“Key 2” == “Key 2 Value 1” OR “Key 2” does not exist))
OR (“Key 3” == “Key 3 Value1”)
json [ { "Key 1": ["Key 1 Value 1", "Key 1 Value 2"], "Key 2": ["Key 2 Value 1", "-1"] }, { "Key 3" : ["Key 3 Value 1"] } ]

–Schedule Retrieval (Individual)

GET :
Test endpoint: [https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}]](https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId})
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}


Sample Response:

{
  "id": 23,
  "companyId": 1234,
  "accountNumber": "456465",
  "status": "COMPLETED",
  "paymentMethod": "CHECK",
  "firstName": "Cashier",
  "lastName": "test",
  "settingId": 2,
  "memo": "Cashier test",
  "addressOne": "3242 Street",
  "city": "myCity",
  "state": "UT",
  "zip": "12345",
  "origin": "EXT",
  "locationId": "2",
  "recurrenceRule": "FREQ=MONTHLY;INTERVAL=1;",
  "createUser": "test@test.com",
  "updateUser": "tester@test.com",
  "createDate": "2018-04-03 15:48:07",
  "updateDate": "2018-08-30 10:44:37",
  "requestPaymentData": false,
  "sendAuthorizationRequest": false,
  "pendingAmount": 0.00,
  "nextPaymentAmount": 0.00,
  "collectedAmount": 100.00,
  "unsuccessfulAmount": 400.00,
  "totalExpectedAmount": 580.00,
  "pendingCount": 0,
  "collectedCount": 4,
  "unsuccessfulCount": 1,
  "totalExpectedCount": 5,
  "initialPaymentAmount": 0,
  "adjustmentAmount": 0,
  "billingLastFour": "1212"
}

Retrieve an individual Schedule object based on the id passed in the URL. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/23

–Schedule Deletion

DELETE :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/{id}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/{id}

Delete an individual schedule by scheduleId. A schedule cannot be deleted if has payments that have been attempted, whether successfully or failed. A schedule that cannot be deleted should be set to INACTIVE with a PATCH request. This request will return no response body, rather just a standard HTTP status code 200 for successful deletion. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/4

–Schedule Render

POST :
Test endpoint: [https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/render]](https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/render)
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/render


Sample Response:

{
  "scheduleId": 17381,
  "includeSignatureImage": false,
  "scheduleHtml": "<!DOCTYPE html><html lang='en' xmlns='http://www.w3.org/1999/xhtml'><head>  <meta charset='utf-8'>  <meta name='viewport' content='width=device-width'>  <meta http-equiv='X-UA-Compatible' content='IE=edge'>  <meta name='x-apple-disable-message-reformatting'>  <title>Schedule Information</title>  <!-- Web Font / @font-face : BEGIN -->  <!-- Desktop Outlook chokes on web font references and defaults to Times New Roman, so we force a safe fallback font. -->  <!--[if mso]>    <style>      * {        font-family: sans-serif !important;      }    </style>  <![endif]-->  <!-- All other clients get the webfont reference; some will render the font and others will silently fail to the fallbacks. -->  <!--[if !mso]><!-->  <link href='https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>  <!--<![endif]-->  <!-- Web Font / @font-face : END -->  <!-- CSS Reset : BEGIN -->  <style>    /* What it does: Remove spaces around the email design added by some email clients. */    /* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */    html,    body {      margin: 0 auto !important;      padding: 0 !important;      height: 100% !important;      width: 100% !important;    }    /* What it does: Stops email clients resizing small text. */    * {      -ms-text-size-adjust: 100%;      -webkit-text-size-adjust: 100%;    }    .value { text-align: right; }    .title { text-align: left; }    /* What it does: Centers email on Android 4.4 */    div[style*='margin: 16px 0'] {      margin: 0 !important;    }    /* What it does: Stops Outlook from adding extra spacing to tables. */    table,    td {      mso-table-lspace: 0pt !important;      mso-table-rspace: 0pt !important;    }    /* What it does: Fixes webkit padding issue. */    table {      border-spacing: 0 !important;      border-collapse: collapse !important;      table-layout: fixed !important;      margin: 0 auto !important;    }    /* What it does: Uses a better rendering method when resizing images in IE. */    img {      -ms-interpolation-mode:bicubic;    }    /* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */    a {      text-decoration: none;    }    /* What it does: A work-around for email clients meddling in triggered links. */    *[x-apple-data-detectors],  /* iOS */    .unstyle-auto-detected-links *,    .aBn {      border-bottom: 0 !important;      cursor: default !important;      color: inherit !important;      text-decoration: none !important;      font-size: inherit !important;      font-family: inherit !important;      font-weight: inherit !important;      line-height: inherit !important;    }    a[href^=tel]{      color:#555;      text-decoration:none;    }    #footer a[href^=tel]{      color:#fef;      text-decoration:none;    }    /* What it does: Prevents Gmail from displaying a download button on large, non-linked images. */    .a6S {      display: none !important;      opacity: 0.01 !important;    }    /* What it does: Prevents Gmail from changing the text color in conversation threads. */    .im {      color: inherit !important;    }    /* If the above doesn't work, add a .g-img class to any image in question. */    img.g-img + div {      display: none !important;    }    /* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89  */    /* Create one of these media queries for each additional viewport size you'd like to fix */    /* iPhone 4, 4S, 5, 5S, 5C, and 5SE */    @media only screen and (min-device-width: 320px) and (max-device-width: 374px) and (-webkit-min-device-pixel-ratio: 3) {      u ~ div .email-container {        min-width: 320px !important;      }    }    /* iPhone 6, 6S, 7, 8, and X */    @media only screen and (min-device-width: 375px) and (max-device-width: 413px) and (-webkit-min-device-pixel-ratio: 2) {      u ~ div .email-container {        min-width: 375px !important;      }    }    /* iPhone 6+, 7+, and 8+ */    @media only screen and (min-device-width: 414px) and (-webkit-min-device-pixel-ratio: 3) {      u ~ div .email-container {        min-width: 414px !important;      }    }    /* iPhone X */    @media only screen and (min-device-width: 375px) and (max-device-width: 812px) and (-webkit-min-device-pixel-ratio: 3) {      u ~ div .email-container {        min-width: 414px !important;      }    }  </style>  <!-- What it does: Makes background images in 72ppi Outlook render at correct size. -->  <!--[if gte mso 9]>  <xml>    <o:OfficeDocumentSettings>      <o:AllowPNG/>      <o:PixelsPerInch>96</o:PixelsPerInch>    </o:OfficeDocumentSettings>  </xml>  <![endif]-->  <!-- CSS Reset : END -->  <!-- Progressive Enhancements : BEGIN -->  <style>    /* Media Queries */    @media screen and (min-width:380px) {    }    @media screen and (min-width:420px) {    }    @media screen and (min-width:460px) {      #scheduleInformation td, #paymentInformation td {        display:table-cell !important;      }      #scheduleInformation td.title, #paymentInformation td.title {        padding:0 5% 0 0 !important;        width:50% !important;      }      #scheduleInformation td.value, #paymentInformation td.value {        padding:0 0 0 5% !important;        text-align:right !important;        width:auto !important;      }      #scheduleInformation td.value h2, #paymentInformation td.value h2 {        font-weight:bold !important;      }    }    @media screen and (min-width:600px) {      #accountInformation table td table td {        display:table-cell !important;      }      #accountInformation table td table td.payee {        padding:0 5% 0 0 !important;        width:60% !important;      }      #accountInformation table td table td.account {        padding:0 0 0 5% !important;        text-align:right !important;        width:auto !important;      }      #accountInformation table td table td h2 {        margin:0 0 10px 0 !important;      }    }  </style>  <!-- Progressive Enhancements : END --></head><body width='100%' style='background-color:#fefefe; margin:0; padding:0 !important; width:100%; mso-line-height-rule:exactly;'><center style='background-color:#fefefe; width:100%;'>    <!--[if mso | IE]>    <table role='presentation' border='0' cellpadding='0' cellspacing='0' width='100%' style='background-color:#fefefe;'>    <tr>    <td>    <![endif]-->      <div style='max-width:720px; margin:0 auto;' class='email-container'>        <!--[if mso]>        <table align='center' role='presentation' cellspacing='0' cellpadding='0' border='0' width='720'>        <tr>        <td>        <![endif]-->        <!-- Email Body : BEGIN -->        <table align='center' role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%' style='margin:auto;'>          <tbody>            <!-- Header Bar : BEGIN -->            <tr>              <td id='header' style='background:#56565A; font-family:Lato,Helvetica Neue,Helvetica,Roboto,Arial,sans-serif; padding:40px; text-align:center;'>              </td>            </tr>            <!-- Header Bar : END -->            <!-- Clear Spacer 40 : BEGIN -->            <tr>              <td class='spacerForty' aria-hidden='true' height='40' style='font-size:0px; line-height:0px;'>                &nbsp;              </td>            </tr>            <!-- Clear Spacer 40 : END -->            <!-- Main Content : BEGIN -->            <tr>              <td id='content' style='color:#56565a; font-family:Lato,Helvetica Neue,Helvetica,Roboto,Arial,sans-serif; font-size:16px; line-height:24px; padding:0 40px;'>                <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                  <tbody>                    <!-- Account Information : BEGIN -->                    <tr>                      <td id='accountInformation'>                        <h1 style='text-align:left; margin:0; font-size:24px; line-height:32px; font-weight:normal;'>Account Information</h1>                        <hr style='margin:20px 0;'>                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                          <tbody>                            <tr>                              <td style='padding:0 20px;'>                                <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                  <tbody>                                    <tr>                                      <td class='payee' style='text-align:left; padding:0 0 20px 0; vertical-align:top; width:100%;'>                                        <h2 style='font-size:20px; font-weight:bold; line-height:30px; margin:0;'>Test McTester</h2>                                        <div>                                          <span style='display:none'></span> <span style='display:display:none;'></span>                                        </div>                                        <div>                                          <span style='display:none;'></span>                                        </div>                                        <div>                                          <span style='display:none'></span>                                        </div>                                      </td>                                      <td class='account' style='text-align:right; padding:0; vertical-align:top; width:100%;'>                                        <h2 style='font-size:20px; font-weight:bold; line-height:30px; margin:0;'>Account Number</h2>                                        <div>                                          123455                                        </div>                                      </td>                                    </tr>                                  </tbody>                                </table>                              </td>                            </tr>                          </tbody>                        </table>                      </td>                    </tr>                    <!-- Account Information : END -->                    <!-- Clear Spacer 40 : BEGIN -->                    <tr>                      <td class='spacerForty' aria-hidden='true' height='40' style='font-size:0px; line-height:0px;'>                        &nbsp;                      </td>                    </tr>                    <!-- Clear Spacer 40 : END -->                    <!-- Schedule Information : BEGIN -->                    <tr>                      <td id='scheduleInformation'>                        <h1 style='text-align:left; margin:0; font-size:24px; line-height:32px; font-weight:normal;'>Schedule Information</h1>                        <hr style='margin:20px 0;'>                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                          <tbody>                            <tr>                              <td style='padding:0 20px;'>                                <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                  <tbody>                                    <tr>                                      <td style='padding:0 5% 0 0; text-align:left; vertical-align:top;'>                                        Amount Owed                                      </td>                                      <td style='padding:0 0 0 5%; text-align:right; vertical-align:top;'>                                        $1,000.00                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : BEGIN -->                                    <tr>                                      <td class='spacerTwenty' colspan='2' aria-hidden='true' height='20' style='font-size:0px; line-height:0px;'>                                        &nbsp;                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : END -->                                    <tr>                                      <td style='padding:0 5% 0 0; text-align:left; vertical-align:top;'>                                        Amount Paid                                      </td>                                      <td style='padding:0 0 0 5%; text-align:right; vertical-align:top;'>                                        $0.00                                      </td>                                    </tr>                                    <tr>                                      <td colspan='2' style=''>                                        <hr style='margin:20px 0;'>                                      </td>                                    </tr>                                    <tr>                                      <td style='padding:0 5% 0 0; text-align:left; vertical-align:top;'>                                        <h2 style='font-size:20px; font-weight:bold; line-height:30px; margin:0;'>Amount Remaining</h2>                                      </td>                                      <td style='padding:0 0 0 5%; text-align:right; vertical-align:top;'>                                        <h2 style='font-size:20px; font-weight:bold; line-height:30px; margin:0;'>$1,000.00</h2>                                      </td>                                    </tr>                                  </tbody>                                </table>                              </td>                            </tr>                            <!-- Clear Spacer 40 : BEGIN -->                            <tr>                              <td class='spacerForty' aria-hidden='true' height='40' style='font-size:0px; line-height:0px;'>                                &nbsp;                              </td>                            </tr>                            <!-- Clear Spacer 40 : END -->                            <tr>                              <td style='padding:0 20px;'>                                <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                  <tbody>                                    <tr>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                          <tr>                                            <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                              Schedule Status                                            </td>                                            <td class='value' style='padding:0; text-align:right; vertical-align:top; width:100%;'>                                              Active                                            </td>                                          </tr>                                          </tbody>                                        </table>                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : BEGIN -->                                    <tr>                                      <td class='spacerTwenty' aria-hidden='true' height='20' style='font-size:0px; line-height:0px;'>                                        &nbsp;                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : END -->                                    <tr>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                          <tr>                                            <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                              Next Payment                                            </td>                                            <td class='value' style='padding:0; vertical-align:top; width:100%;'>                                              $100.00 on 01/24/2020                                            </td>                                          </tr>                                          <!-- Clear Spacer 20 : BEGIN -->                                          <tr>                                            <td class='spacerTwenty' aria-hidden='true' height='20' style='font-size:0px; line-height:0px;'>                                              &nbsp;                                            </td>                                            <td class='spacerTwenty' aria-hidden='true' height='20' style='font-size:0px; line-height:0px;'>                                              &nbsp;                                            </td>                                          </tr>                                          <!-- Clear Spacer 20 : END -->                                          </tbody>                                        </table>                                      </td>                                    </tr>                                    <tr>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                          <tr>                                            <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                              Schedule Frequency                                            </td>                                            <td class='value' style='padding:0; vertical-align:top; width:100%;'>                                              Once per month                                            </td>                                          </tr>                                          </tbody>                                        </table>                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : BEGIN -->                                    <tr>                                      <td class='spacerTwenty' aria-hidden='true' height='20' style='font-size:0px; line-height:0px;'>                                        &nbsp;                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : END -->                                    <tr>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                          <tr>                                            <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                              Remaining Payments                                            </td>                                            <td class='value' style='padding:0; vertical-align:top; width:100%;'>                                              10                                            </td>                                          </tr>                                          </tbody>                                        </table>                                      </td>                                    </tr>                                    <tr style='display:none'>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                          <!-- Clear Spacer 20 : BEGIN -->                                          <tr>                                            <td class='spacerTwenty' aria-hidden='true' height='20' style='font-size:0px; line-height:0px;'>                                              &nbsp;                                            </td>                                          </tr>                                          <!-- Clear Spacer 20 : END -->                                          <tr>                                            <td>                                              <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                                <tbody>                                                  <tr>                                                    <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                                      Memo                                                    </td>                                                    <td class='value' style='padding:0; vertical-align:top; width:100%;'>                                                      <p style='line-height:20px; margin:0;'></p>                                                    </td>                                                  </tr>                                                </tbody>                                              </table>                                            </td>                                          </tr>                                          </tbody>                                        </table>                                      </td>                                    </tr>                                  </tbody>                                </table>                              </td>                            </tr>                          </tbody>                        </table>                      </td>                    </tr>                    <!-- Schedule Information : END -->                    <!-- Clear Spacer 40 : BEGIN -->                    <tr>                      <td class='spacerForty' aria-hidden='true' height='40' style='font-size:0px; line-height:0px;'>                        &nbsp;                      </td>                    </tr>                    <!-- Clear Spacer 40 : END -->                    <!-- Payment Information : BEGIN -->                    <tr>                      <td id='paymentInformation'>                        <h1 style='text-align:left; margin:0; font-size:24px; line-height:32px; font-weight:normal;'>Payment Information</h1>                        <hr style='margin:20px 0;'>                        <!-- Card Payment : Begin -->                        <table id='cardPayment' style='display:none' role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                          <tbody>                            <tr>                              <td style='padding:0 20px;'>                                <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                  <tbody>                                    <tr>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                            <tr>                                              <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                                Card Number                                              </td>                                              <td class='value' style='padding:0; vertical-align:top; width:100%;'>                                                ************                                              </td>                                            </tr>                                          </tbody>                                        </table>                                      </td>                                    </tr>                                  </tbody>                                </table>                              </td>                            </tr>                          </tbody>                        </table>                        <!-- Card Payment : END -->                        <!-- Check Payment : BEGIN -->                        <table id='checkPayment' role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                          <tbody>                            <tr>                              <td style='padding:0 20px;'>                                <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                  <tbody>                                    <tr>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                            <tr>                                              <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                                Bank Account Number                                              </td>                                              <td class='value' style='padding:0; vertical-align:top; width:100%;'>                                                ******4321                                              </td>                                            </tr>                                          </tbody>                                        </table>                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : BEGIN -->                                    <tr>                                      <td class='spacerTwenty' aria-hidden='true' height='20' style='font-size:0px; line-height:0px;'>                                        &nbsp;                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : END -->                                    <tr>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                            <tr>                                              <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                                Bank Routing Number                                              </td>                                              <td class='value' style='padding:0; vertical-align:top; width:100%;'>                                                123456789                                              </td>                                            </tr>                                          </tbody>                                        </table>                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : BEGIN -->                                    <tr>                                      <td class='spacerTwenty' aria-hidden='true' height='20' style='font-size:0px; line-height:0px;'>                                        &nbsp;                                      </td>                                    </tr>                                    <!-- Clear Spacer 20 : END -->                                    <tr>                                      <td>                                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                          <tbody>                                            <tr>                                              <td class='title' style='font-weight:bold; padding:0; vertical-align:top; width:100%;'>                                                Bank Account Type                                              </td>                                              <td class='value' style='padding:0; vertical-align:top; width:100%;'>                                                Checking                                              </td>                                            </tr>                                          </tbody>                                        </table>                                      </td>                                    </tr>                                  </tbody>                                </table>                              </td>                            </tr>                          </tbody>                        </table>                        <!-- Check Payment : END -->                      </td>                    </tr>                    <!-- Payment Information : END -->                    <!-- Clear Spacer 40 : BEGIN -->                    <tr>                      <td class='spacerForty' aria-hidden='true' height='40' style='font-size:0px; line-height:0px;'>                        &nbsp;                      </td>                    </tr>                    <!-- Clear Spacer 40 : END -->                    <!-- Payment Schedule : BEGIN -->                    <tr>                      <td id='paymentSchedule'>                        <h1 style='text-align:left; margin:0; font-size:24px; line-height:32px; font-weight:normal;'>Payment Schedule</h1>                        <hr style='margin:20px 0;'>                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                          <tbody>                            <tr>                              <td style='padding:0 20px;'>                                <div style='border:1px solid #cacaca; overflow-x:auto; width:100%;'>                                  <table style='table-layout:initial !important;' role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                    <thead>                                      <tr style='background:#cacaca;'>                                        <th style='padding:10px 10px 10px 20px; text-align:left;'>                                          Date                                        </th>                                        <th style='padding:10px 20px; text-align:right;'>                                          Amount                                        </th>                                        <th style='padding:10px 20px 10px 10px; text-align:left;'>                                          Status                                        </th>                                      </tr>                                    </thead>                                    <tbody>                                      <tr class='oddRow' style='background:#fefefe;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    01/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='evenRow' style='background:#f1f1f1;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    02/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='oddRow' style='background:#fefefe;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    03/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='evenRow' style='background:#f1f1f1;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    04/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='oddRow' style='background:#fefefe;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    05/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='evenRow' style='background:#f1f1f1;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    06/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='oddRow' style='background:#fefefe;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    07/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='evenRow' style='background:#f1f1f1;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    08/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='oddRow' style='background:#fefefe;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    09/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr><tr class='evenRow' style='background:#f1f1f1;'>  <td style='padding:10px 10px 10px 20px; text-align:left; vertical-align:top;'>    10/24/2020  </td>  <td style='padding:10px 20px; text-align:right; vertical-align:top;'>    $100.00  </td>  <td style='padding:10px 20px 10px 10px; text-align:left; vertical-align:top;'>    Pending  </td></tr>                                    </tbody>                                  </table>                                </div>                              </td>                            </tr>                          </tbody>                        </table>                      </td>                    </tr>                    <!-- Payment Schedule : END -->                    <!-- Clear Spacer 40 : BEGIN -->                    <tr>                      <td class='spacerForty' aria-hidden='true' height='40' style='font-size:0px; line-height:0px;'>                        &nbsp;                      </td>                    </tr>                    <!-- Clear Spacer 40 : END -->                    <!-- Signature Image : BEGIN -->                    <tr style='display:none'>                      <td id='signatureConfirmation'>                        <h1 style='margin:0; font-size:24px; line-height:32px; font-weight:normal;'>Signature                          Confirmation</h1>                        <hr style='margin:20px 0;'>                        <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                          <tbody>                          <tr>                            <td style='padding:0 20px;'>                              <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                                <tbody>                                <tr>                                  <td style='text-align:center; vertical-align:top; width:100%;'>                                    <div id='signatureConfirmationContainer'                                         style='border:1px solid #cacaca; box-sizing:border-box; padding:2%; position:relative; width:100%;'>                                      <div id='signatureConfirmationImage'                                           style='margin:0 auto; position:relative; max-width:535px; width:100%; z-index:4;'>                                        <img src='data:image/png;base64,'                                             alt='Signature Confirmation' style='max-width:100%;'>                                      </div>                                      <div id='signatureConfirmationLine'                                           style='background:#cacaca; height:2px; position:absolute; top:70%; width:96%; z-index:1;'></div>                                      <div class='signatureConfirmationX'                                           style='background:#cacaca; height:30%; left:6%; position:absolute; top:35%; transform:rotate(34deg); -webkit-transform-style: preserve-3d; -webkit-transform: rotateZ(34deg); width:1%; z-index:2;'></div>                                      <div class='signatureConfirmationX'                                           style='background:#cacaca; height:30%; left:6%; position:absolute; top:35%; transform:rotate(-34deg); -webkit-transform-style: preserve-3d; -webkit-transform: rotateZ(-34deg); width:1%; z-index:2;'></div>                                    </div>                                  </td>                                </tr>                                </tbody>                              </table>                            </td>                          </tr>                          <!-- Clear Spacer 40 : BEGIN -->                          <tr>                            <td class='spacerForty' aria-hidden='true' height='40' style='font-size:0px; line-height:0px;'>                              &nbsp;                            </td>                          </tr>                          <!-- Clear Spacer 40 : END -->                          </tbody>                        </table>                      </td>                    </tr>                    <!-- Signature Image : END -->                  </tbody>                </table>              </td>            </tr>            <!-- Main Content : END -->            <!-- Custom Text : BEGIN -->            <tr>              <td id='customText'>                <hr style='margin:0 0 40px 0;'>                <table role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%'>                  <tbody>                  <tr>                    <td style='color:#56565a; font-family:Lato,Helvetica Neue,Helvetica,Roboto,Arial,sans-serif; font-size:16px; line-height:24px; padding:0 40px;'>                      <table>                        <tbody>                        <!-- Custom Text : BEGIN -->                        <tr>                          <td style='text-align:center;'>                            After this schedule text                          </td>                        </tr>                        <!-- Custom Text : END -->                        <!-- Clear Spacer 40 : BEGIN -->                        <tr>                          <td class='spacerForty' aria-hidden='true' height='40' style='font-size:0px; line-height:0px;'>                            &nbsp;                          </td>                        </tr>                        <!-- Clear Spacer 40 : END -->                        </tbody>                      </table>                    </td>                  </tr>                  </tbody>                </table>              </td>            </tr>            <!-- Custom Text : END -->            <!-- Footer Bar : BEGIN -->            <tr id='footer'>              <td style='background:#56565a; color:#fefefe; font-family:Lato,Helvetica Neue,Helvetica,Roboto,Arial,sans-serif; font-size:16px; line-height:24px; padding:40px; text-align:center;'>              <h2 style='font-size:20px; font-weight:normal; line-height:30px; margin:0 0 20px 0;'>Demonstration Company</h2>                <div>                  Just an address                 </div>                <div>                  OKLAHOMA CITY, OK 73119                </div>                <div style='display:none'>                  <span style='margin:20px 0 0 0;'>Customer Support : <a style='color:#fefefe;'></a></span>                </div>                <div style='margin:40px 0 0 0;'>                  <small><i>01/13/2020 14:48 PM</i></small>                </div>              </td>            </tr>            <!-- Footer Bar : END -->          </tbody>        </table>        <!-- Email Body : END -->        <!--[if mso]>        </td>        </tr>        </table>        <![endif]-->      </div>    <!--[if mso | IE]>    </td>    </tr>    </table>    <![endif]-->  </center></body></html>"
}

Retrieve an HTML representation of an individual Schedule object based on the id passed in the request. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/render

Attribute Description
scheduleId
Numeric10
The id of the schedule for which to generate the render.
emailTo
ListN/A
A list of email addresses to send the HTML render to.
emailCC
ListN/A
A list of email addresses to CC send the HTML render to.
emailBCC
ListN/A
A list of email addresses to BCC send the HTML render to.
scheduleHtml
AlphanumericN/A
The HTML render of the schedule.
includeSignatureImage
BooleanN/A
Whether to include the signature image on the schedule render. A signature image will only be present if sendAuthorizationRequest was originally set to true and the signature request was completed successfully.

Schedule Payments

Use this endpoint to add, edit or remove payments from an existing schedule.
POST to add a new payment.
PUT to overwrite an existing payment by paymentId.
GET to retrieve list of schedule payments.
GET to retrieve single schedule payments by paymentId.
DELETE to delete single schedule payment by paymentId.

Schedule Payment Object

Full Payment Object

Payment Object:

{
  "paymentId": 2,
  "status": "ERROR",
  "paymentAmount": 300.00,
  "paymentDate": "2019-12-08",
  "arrivalId": 4,
  "paymentAttempts": [
    {
      "arrivalId": 4,
      "attemptDate": "2019-12-08T11:01:23.000+0000",
      "status": "ERROR",
      "statusMessage": "Request error: Field can only contain numeric and dash characters. "
    }
  ]
}
Attribute Description
paymentId
Numeric20
Id for the payment record.
scheduleId
Numeric10
Id for the parent schedule object.
status
AlphaN/A
The current status of the payment.
Valid value(s):
PENDING - The payment is waiting to be processed.
WAITING - The ACH payment wil be submitted with the current day’s batch.
PULLED - The ACH payment has been pulled from the account.
ACKNOWLEDGED - The ACH payment has been submitted to the bank and acknowledged by the bank as received.
REJECTED - The ACH payment was rejected.
SUBMITTED - The ACH payment has been submitted to the bank.
VOID - The payment has been voided.
PAID - The payment has processed successfully.
FUNDED - The ACH payment has funded successfully.
NSF - The ACH payment was rejected by the bank due to non-sufficient funds.
RETURNED - The ACH payment was returned.
NSF_DEDUCTION - The ACH payment was deducted due to non-sufficient funds.
DECLINED - The card payment was declined.
CORRECTION - The ACH payment funded successfully but has a corrected bank account or routing number.
ERROR - The payment failed to process.
RETRY - The payment failed to process initially, but will be tried again.
CANCELLED - The payment was marked as cancelled and will not be processed.
SKIPPED - No attempt to process the payment was made and it is past due. This would happen if a schedule was INACTIVE then later activated.
DEDUCTION - Payment was returned after being funded.
paymentAmount
Numeric11
Payment amount for this payment.
paymentDate
Date19
Date the payment is scheduled to post, formatted “yyyy-MM-dd”.
Format: URL Encoded ISO-8601
arrivalId
Numeric11
The arrivalId of the last payment attempt. This will only exist if a payment has been attempted.
transactionId
Numeric20
The transaction id of the last payment. This will only exist if a payment has been processed successfully.
paymentAttempts
List
READONLY
This is a list of attempts to process this payment, and the results of those attempts.
Details
Attribute Description
paymentId
Numeric20
The id of the payment the attempt was made for.
arrivalId
Numeric11
The arrival id of the attempted transaction.
transactionId
Numeric20
The transaction id of the payment. This will only be present on a successful transaction.
attemptDate
Date19
The date that the attempt to post this payment was made.
status
AlphaN/A
The status of the payment attempt.
Valid value(s):
PENDING, WAITING, PULLED, ACKNOWLEDGED, REJECTED, SUBMITTED, VOID, PAID, FUNDED, NSF, RETURNED, NSF_DEDUCTION, DECLINED, CORRECTION, ERROR, RETRY, CANCELLED, SKIPPED
statusMessage
Alphanumeric255
Any messages that are a result of the payment attempt.

–Payment Creation

POST :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedulepayments
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedulepayments


Sample Response:

{
  "paymentId": 6,
  "status": "PENDING",
  "paymentAmount": 300.00,
  "paymentDate": "2019-12-08"
}

POST to create a new payment on a schedule.

Attribute Description
scheduleId
Numeric10
Id for the parent schedule object.
paymentAmount
Numeric11
Payment amount for this payment.
paymentDate
Date19
Date the payment is scheduled to post, formatted “yyyy-MM-dd”.
Format: URL Encoded ISO-8601

–Payment Modification

PUT :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/{schedulepaymentId}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/{schedulepaymentId}


Sample Response:

{
  "paymentId": 6,
  "status": "PENDING",
  "paymentAmount": 300.00,
  "paymentDate": "2019-12-08"
}

PUT requests will completely override the existing specified (by schedulePaymentId payment in the URL) setting. As such, the request object the same as the payment creation.

Payment Modification
Attribute Description
scheduleId
Numeric10
Id for the parent schedule object.
paymentAmount
Numeric11
Payment amount for this payment.
paymentDate
Date19
Date the payment is scheduled to post, formatted “yyyy-MM-dd”.
Format: URL Encoded ISO-8601

–Payment Retrieval (Individual)

GET :
Test endpoint: [https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/{schedulepaymentId}]](https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/{schedulepaymentId})
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/{schedulepaymentId}


Sample Response:

{
  "paymentId": 2,
  "status": "ERROR",
  "paymentAmount": 300.00,
  "paymentDate": "2019-12-08",
  "arrivalId": 4,
  "paymentAttempts": [
    {
      "arrivalId": 4,
      "attemptDate": "2019-12-08T11:01:23.000+0000",
      "status": "ERROR",
      "statusMessage": "Request error: Field can only contain numeric and dash characters. "
    }
  ]
}

Retrieve an individual Payment object based on the id passed in the URL. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/2

–Payment Deletion

DELETE :
Test endpoint: https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/{id}
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/{id}

Delete an individual payment by schedulePaymentId. A payment can only be deleted if it is in PENDING status. This request will return no response body, rather just a standard HTTP status code 200 for successful deletion. https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedulepayments/4

Schedule History

GET to retrieve list of histories for a schedule.

Schedule History Object

Full History Object

History Object:

{
  "date": "2020-01-08 04:01:22",
  "event": "PAYMENT_ATTEMPT",
  "eventId": 7,
  "user": "recurring",
  "data": "Request error: Field can only contain numeric and dash characters. "
}
Attribute Description
event
AlphaN/A
Valid value(s):
CREATE
SCHEDULE_MODIFY
SCHEDULE_STATUS
BILLING_MODIFY
PAYMENT_ATTEMPT
FLOW_RESULT
AUTHORIZATION_REQUEST
BILLING_REQUEST
eventId
Numeric
The id of the related EVENT.
data
Alphanumeric 255
Free form text description of the event.
date
Date19
The date the history was added.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
user
Alphanumeric75
User that added the history.

–History Retrieval (List)

GET :
Test endpoint: [https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}/histories]](https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}/histories)
Live endpoint: https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}/histories


Sample Response:

{
  "scheduleHistoryList": [
    {
      "date": "2019-11-07 12:49:52",
      "event": "CREATE",
      "eventId": 3,
      "user": "test"
    },
    {
      "date": "2019-11-07 12:49:53",
      "event": "AUTHORIZATION_REQUEST",
      "eventId": 4,
      "user": "test",
      "data": "Authorization request HTTP response status: 200 OK"
    },
    {
      "date": "2019-11-07 12:49:52",
      "event": "FLOW_REQUEST",
      "eventId": 5,
      "user": "test"
    },
    {
      "date": "2019-11-07 12:56:08",
      "event": "FLOW_RESULT",
      "user": "signatureUI",
      "data": "FlowId: 5 Updated with status of AUTHORIZED"
    },
    {
      "date": "2019-11-07 12:56:11",
      "event": "FLOW_RESULT",
      "user": "signatureUI",
      "data": "FlowId: 5 Updated with status of COMPLETED"
    },
    {
      "date": "2019-12-08 04:01:23",
      "event": "PAYMENT_ATTEMPT",
      "eventId": 6,
      "user": "recurring",
      "data": "Request error: Field can only contain numeric and dash characters. "
    },
    {
      "date": "2020-01-08 04:01:22",
      "event": "PAYMENT_ATTEMPT",
      "eventId": 7,
      "user": "recurring",
      "data": "Request error: Field can only contain numeric and dash characters. "
    }
  ]
}

Retrieve an list of ScheduleHistory objects for the schedule id passed in the URL. Optional Parameter: eventType - Type of history event to search for
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/2/histories?eventType=

Attribute Description
eventType
AlphaN/A
Valid value(s):
CREATE - The schedule was created.
SCHEDULE_MODIFY - The schedule was modified.
SCHEDULE_STATUS - The schedule status was changed.
BILLING_MODIFY - The billing data on the schedule was modified.
PAYMENT_ATTEMPT - An attempt to process a payment was made.
FLOW_RESULT - The status of an attached flow was changed.
AUTHORIZATION_REQUEST - An authorization request was sent.
BILLING_REQUEST - Billing data was updated from an flow request.

For Reference

These objects are used or returned in the requests and responses above. They are listed here for quick reference.

–Billing Card

Billing Card Object


cardToken
Alphanumeric 16
Required
The credit card token. This must be a token, and not a raw credit card number.
To create a token, see Secure Overlay API and/or TokenizationService.
expirationMonth
Numeric 2
Conditional
The credit card expiration month.
This value will be retrieved from the cardToken if not provided. Required if expirationYear is provided.
expirationYear
Numeric 2
Conditional
The credit card expiration year.
This value will be retrieved from the cardToken if not provided. Required if expirationMonth is provided.
accountDirective
Alphanumeric 10
Required
The account directive that defines which card merchant account to use for processing the schedule payments.

–Billing Check

Billing Check Object


routingNumber
Numeric 9
Conditional
The bank routing number for processing the schedule payments.
Required if a raw bankAccountNumber is provided. Otherwise it is retrieved from a token bankAccountNumber if not provided.
bankAccountNumber
Alphanumeric 20
Required
A bank Token or a raw bank account number to use for processing the schedule payments.
To create a token, see Secure Overlay API and/or TokenizationService.
NOTE: Providing a raw bank account number is deprecated. When a raw bank account number is provided, the bankAccountNumber, routingNumber, and bankAccountType will be Tokenized and the Token will be returned here as the bankAccountNumber
bankAccountType
Alpha
N/A
Conditional
Valid values:
CHECKING
SAVINGS
Required if a raw bankAccountNumber is provided. Otherwise it is retrieved from a token bankAccountNumber if not provided.
accountDirective
Alphanumeric 10
Required
The account directive that defines which check merchant account to use for processing the schedule payments.

–Custom Receipt Labels

Custom Receipt Labels Object


Attribute Description
PAYMENT
Alphanumeric30
Default value: Payment.
ACCOUNT_NUMBER
Alphanumeric30
Default value: Account number.
MEMO
Alphanumeric30
Default value: Memo.
BANK_ACCOUNT_TYPE
Alphanumeric30
Default value: Bank account type. Only applies to a CHECK paymentMethod.

–Custom Render Labels

Custom Render Labels Object


Attribute Description
ACCOUNT_NUMBER
Alphanumeric30
Default value: Account Number.
AMOUNT_OWED
Alphanumeric30
Default value: Amount Owed.
INITIAL_PAYMENT
Alphanumeric30
Default value: Initial Payment.
AMOUNT_PAID
Alphanumeric30
Default value: Amount Paid.
AMOUNT_REMAINING
Alphanumeric30
Default value: Amount Remaining.
SCHEDULE_STATUS
Alphanumeric30
Default value: Schedule Status.
NEXT_PAYMENT
Alphanumeric30
Default value: Next Payment.
SCHEDULE_INTERVAL
Alphanumeric30
Default value: Schedule Interval.
REMAINING_PAYMENTS
Alphanumeric30
Default value: Remaining Payments.
MEMO
Alphanumeric30
Default value: Memo.
BANK_ACCOUNT_NUMBER
Alphanumeric30
Default value: Bank Account Number. Only applies to a CHECK paymentMethod.
BANK_ROUTING_NUMBER
Alphanumeric30
Default value: Bank Routing Number. Only applies to a CHECK paymentMethod.
BANK_ACCOUNT_TYPE
Alphanumeric30
Default value: Bank Account Type. Only applies to a CHECK paymentMethod.
CARD_NUMBER
Alphanumeric30
Default value: Card Number. Only applies to a CARD paymentMethod.
CARD_EXPIRATION
Alphanumeric30
Default value: Expiration. Only applies to a CARD paymentMethod.

–Flow Request

Flow Request Object


Attribute Description
flowId
Numeric 9
The id of the flow request.
status
Alpha N/A
The current status of the Flow request. Valid values:
PENDING - The flow request has been sent and is awaiting completion.
EXPIRED - The flow request has expired and can no longer be completed.
COMPLETED - The flow request was successfully completed.
AUTHORIZED - The flow request has been signed. Any further steps may still be pending.
BILLING_RECEIVE - The billing data requested has been received. Any further steps (such as signing authorization) may still be pending.
CANCELED - The flow request was cancelled by the user.
FAILED - The flow request failed to send.
statusDate
Date19
The date the flow was last updated.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
flowResultList
ListN/A
List of FlowResult objects.
Each step of the flow completed by the end user will generate a new FlowResult for the action the user took. Description: See object definition below.

–Flow Result

Flow Result Object


Attribute Description
id
Numeric20
The id of the flow result.
flowId
Numeric
The id of the flow request that this result belongs to.
status
AlphaN/A
The status of this flow result. Valid values:
PENDING - The flow request has been sent and is awaiting completion.
EXPIRED - The flow request has expired and can no longer be completed.
COMPLETED - The flow request was successfully completed.
AUTHORIZED - The flow request has been signed. Any further steps may still be pending.
BILLING_RECEIVE - The billing data requested has been received. Any further steps (such as signing authorization) may still be pending.
CANCELED - The flow request was cancelled by the user.
FAILED - The flow request failed to send.
statusDate
Date19
The date the flow was updated.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
scheduleId
Date10
The id of the schedule that this flow request belongs to.
username
Date75
The user that updated the flow request. This will likely be signatureUI.

–Recur Setting

Recur Setting Object


Attribute Description
paymentTypes
AlphaN/A
The payment types that will be allowed on a schedule.
Valid value(s):
CHECK - check transaction will be processed
CARD - card transaction will be processed
minimumPaymentAmount
Numeric
The minimum payment allowed on a schedule payment. This value must be between 1 and 10000.
allowedFrequencies
AlphaN/A
The allowed payment frequencies in a list.
Valid value(s):
MONTHLY - once per month
BI_MONTHLY - 2 times per month
BI_WEEKLY - once every 2 weeks
WEEKLY - once per week
DAILY - once per day
checkReminderDays
Numeric
The number of days prior to a check payment to send a reminder. This value must be between 3 and 14.
cardReminderDays
Numeric
The number of days prior to a card payment to send a reminder. This value must be between 3 and 14.
recurrenceRule
Alphanumeric255
This is the recurrence rule that you want the schedules using this setting to calculate the payments against. This follows the ICal RRule standard, with the exception that DTSTART will only accept yyyyMMdd format. Any timestamp included as part of DTSTART will be ignored. There is also no need to start a rule with “RRULE=” Example valid rule “FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;”. The DTSTART value cannot be in the past or more than maxDaysToStart days in the future and needs to be formatted “yyyyMMdd”. The INTERVAL has the following valid ranges: MONTHLY 1-12, WEEKLY 1-5, DAILY 1-31.
maxDaysToStart
Numeric3
The number of days in the future that a schedule must start when providing DTSTART in the Schedule recurrenceRule. Defaults to 13 months if not provided.

–Payment Attempt

Payment Attempt


Attribute Description
paymentId
Numeric20
The id of the payment the attempt was made for.
arrivalId
Numeric11
The arrival id of the attempted transaction.
transactionId
Numeric20
The transaction id of the payment. This will only be present on a successful transaction.
attemptDate
Date19
The date that the attempt to post this payment was made.
status
AlphaN/A
The status of the payment attempt.
Valid value(s):
PENDING - The payment is waiting to be processed.
WAITING - The ACH payment wil be submitted with the current day’s batch.
PULLED - The ACH payment has been pulled from the account.
ACKNOWLEDGED - The ACH payment has been submitted to the bank and acknowledged by the bank as received.
REJECTED - The ACH payment was rejected.
SUBMITTED - The ACH payment has been submitted to the bank.
VOID - The payment has been voided.
PAID - The payment has processed successfully.
FUNDED - The ACH payment has funded successfully.
NSF - The ACH payment was rejected by the bank due to non-sufficient funds.
RETURNED - The ACH payment was returned.
NSF_DEDUCTION - The ACH payment was deducted due to non-sufficient funds.
DECLINED - The card payment was declined.
CORRECTION - The ACH payment funded successfully but has a corrected bank account or routing number.
ERROR - The payment failed to process.
RETRY - The payment failed to process initially, but will be tried again.
CANCELLED - The payment was marked as cancelled and will not be processed.
SKIPPED - No attempt to process the payment was made and it is past due. This would happen if a schedule was INACTIVE then later activated.
statusMessage
Alphanumeric255
Any messages that are a result of the payment attempt.

Sample Code

This section offers some client implementation examples in different languages. Keep in mind, these are only minimalistic examples used to demonstrate the Transaction Service REST API and are not meant for production use.
A Jason Web Token (JWT) is required to process all requests through the ScheduleService. You can request a JWT through the GWAuthenticationService, using your company’s username and password, as shown below.

Result Status Codes

Expected Http Status codes

Status '200':
Description = 'Success.'

Status: '400':
Description = 'Malformed request. The request is either incorrectly formatted, or there are validation errors.'

Status '401':
Description = 'Invalid credentials.'

Status '403':
Description = 'Service not activated.'

Status '404':
Description = 'The requested signature/document/image was not found.'

Status '405':
Description = 'POST, GET, PUT request not supported for resource.'

Status '500':
Description = 'An internal error has occurred.'

Sample Create Setting request

<?php
$url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/previews';

$authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');

$scheduleSetting = [
  'name' => 'MySettingName',
  'recurSetting' => "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
  'user' => 'testUser'
];


$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($scheduleSetting, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
    $authorization]
);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

    my $scheduleSetting = {
        'name' => 'MySettingName',
        'recurSetting' => "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
        'user' => 'testUser'
    }

    $data = JSON::XS->new->utf8->encode ($scheduleSetting);
    my $url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings';

    my $req = HTTP::Request->new( 'POST', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    scheduleSetting = {
        'name' => 'MySettingName',
        'recurSetting' => "{\"recurrenceRule\":\"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1;\",\"paymentTypes\":[\"CARD\",\"CHECK\"],\"minimumPaymentAmount\":\"25\",\"allowedFrequencies\":[\"MONTHLY\",\"WEEKLY\",\"BI_WEEKLY\",\"BI_MONTHLY\"],\"checkReminderDays\":\"10\",\"cardReminderDays\":\"5\"}",
        'user' => 'testUser'
    }

    c = Curl::Easy.new
    c.url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = scheduleSetting.to_json.length
    headers['Authorization'] = 'BASIC jws_from_gwauthenticationservice'
    payload = scheduleSetting.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

This will create a Setting. The settingId that is returned can be used in Schedule creation to use this Setting with that Schedule

Send an HTTP POST request to:
test url:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings
live url:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings

Sample Get Settings request

<?php
$settingId = 2;
$url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/'.$settingId;

$authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, [
  'Content-Type: application/json',
  $authorization
]);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $settingId = 2;
   my $uri = URI->new("https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/".$settingId);

   my $req = HTTP::Request->new( 'GET', $uri );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

   settingId = 2;
   url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/' + settingId

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

This will retrieve a ScheduleSetting, specified by the settingId in the URL.

Send an HTTP POST request to:
test url:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/2
live url:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/2

Sample Create Recurring Term request

<?php
$url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms';

$authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');

$recurringTerm = [
  "maximumAmount" => 1000,
  "termMonth"=> 36,
  "user"=> "testUser"
];


$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($recurringTerm, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
    $authorization]
);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

    my $recurringTerm = {
        "maximumAmount" => 1000,
        "termMonth"=> 36,
        "user"=> "testUser"
    }

    $data = JSON::XS->new->utf8->encode ($recurringTerm);
    my $url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms';

    my $req = HTTP::Request->new( 'POST', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    recurringTerm = {
        "maximumAmount" => 1000,
        "termMonth"=> 36,
        "user"=> "testUser"
    }

    c = Curl::Easy.new
    c.url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = recurringTerm.to_json.length
    payload = recurringTerm.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

This will create a RecurringTerm. Any schedules created with an owedAmount less than or equal to $1000 will have a max run time of 36 months.

Send an HTTP POST request to:
test url:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms
live url:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms

Sample Update Recurring Term request

<?php
$url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/6';

$authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');

$recurringTerm = [
  "maximumAmount" => 1000,
  "termMonth"=> 24,
  "user"=> "testUser"
];


$curl = curl_init();

curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
$data = json_encode($recurringTerm, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
    $authorization]
);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

    my $recurringTerm = {
        "maximumAmount" => 1000,
        "termMonth"=> 36,
        "user"=> "testUser"
    }

    $data = JSON::XS->new->utf8->encode ($recurringTerm);
    my $url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/6';

    my $req = HTTP::Request->new( 'PUT', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    recurringTerm = {
        "maximumAmount" => 1000,
        "termMonth"=> 36,
        "user"=> "testUser"
    }

    c = Curl::Easy.new
    c.url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/6'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = recurringTerm.to_json.length
    payload = recurringTerm.to_json

    c.headers = headers
    c.http_put(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

This will update the RecurringTerm with the id 6. Any schedules created with an owedAmount less than or equal to $1000 will now have a max run time of 24 months.

Send an HTTP PUT request to:
test url:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/{recurringTermId}
live url:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/{recurringTermId}

Sample Get Recurring Terms request

<?php

$url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms';

$authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');


$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, [
  'Content-Type: application/json',
  $authorization
]);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $settingId = 2;
   my $uri = URI->new("https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/");

   my $req = HTTP::Request->new( 'GET', $uri );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

   settingId = 2;
   url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/'

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

This will retrieve a list of all your RecurringTerm objects. A recurring term with no maximumAmount defines the maximum run time of schedules that exceed the amount specified by the highest maximumAmount.

Send an HTTP POST request to:
test url:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/
live url:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/settings/recurringterms/

Sample SchedulePreview request

<?php
    $url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/previews';

    $authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');

    $schedulePreview = [
      'owedAmount' => '2000.00',
      'initialPaymentAmount' => '500.00',
      'adjustmentAmount' => '100.00',
      'numberOfPayments' => '0',
      'paymentAmount' => '50.00',
      'settingId' => '16',
      'recurrenceRule' => 'FREQ=WEEKLY;INTERVAL=1;BYMONTHDAY=1;DTSTART=20201116Y000000',
    ];


    $curl = curl_init();

    curl_setopt($curl, CURLOPT_POST, 1);
    $data = json_encode($schedulePreview, JSON_UNESCAPED_SLASHES);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    curl_setopt($curl, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
                'Content-Length: ' . strlen($data),
                $authorization]
    );
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);  //num seconds to try connecting
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

    $result = curl_exec($curl);

    $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    // View response
    print_r(json_decode($result, true));

    if($statusCode == '200') {
      echo $result;
    }
    else {
      echo "Error #:" . $statusCode;
    }
    curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

    my $schedulePreview = {
      'owedAmount' => '2000.00',
      'initialPaymentAmount' => '500.00',
      'adjustmentAmount' => '100.00',
      'numberOfPayments' => '0',
      'paymentAmount' => '50.00',
      'settingId' => '16',
      'recurrenceRule' => 'FREQ=WEEKLY;INTERVAL=1;BYMONTHDAY=1;DTSTART=20201116Y000000',
    }

    $data = JSON::XS->new->utf8->encode ($schedulePreview);
    my $url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/previews';

    my $req = HTTP::Request->new( 'POST', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    schedulePreview = {
      'owedAmount' => '2000.00',
      'initialPaymentAmount' => '500.00',
      'adjustmentAmount' => '100.00',
      'numberOfPayments' => '0',
      'paymentAmount' => '50.00',
      'settingId' => '16',
      'recurrenceRule' => 'FREQ=WEEKLY;INTERVAL=1;BYMONTHDAY=1;DTSTART=20201116Y000000',
    }

    c = Curl::Easy.new
    c.url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/previews'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = schedulePreview.to_json.length
    payload = schedulePreview.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

This will create a SchedulePreview. SchedulePayments generated through this method will contain only a paymentAmount and paymentDate and will not be saved until the schedules endpoint is called with a POST or PUT request.

Send an HTTP POST request to:
test url:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/previews
live url:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/previews

Sample Schedule Creation request

<?php
$url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules';

$authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');

$schedule = [
  'firstName'=>'Test',
  'lastName'=>'McTesty',
  'accountNumber'=>'123455',
  'owedAmount'=>'1000',
  'settingId'=>'2',
  'numberOfPayments'=>'',
  'paymentAmount'=>'100',
  'initialPaymentAmount'=>'',
  'adjustmentAmount'=>'',
  'username'=>'testUser',
  'paymentMethod'=>'CHECK',
  'phoneNumber'=>'',
  'status'=>'ACTIVE',
  'emailAddress'=>'test@test.com',
  'memo'=>'',
  'origin'=>'EXT',
  'recurrenceRule'=>'FREQ=MONTHLY;INTERVAL=1;',
  'sendReceiptToEmailAddress'=>'true',
  'sendAuthorizationRequest'=>'true',
  'requestPaymentData'=>'false',
  'authorization'=>[
    'pinDescription'=>'Last 4 of card number',
    'verificationPin'=>'1234',
    'timeoutMinutes'=>'30',
    'eventRecipientList'=>[
        [
            'emailAddress'=>'someone@example.com'
        ]
    ]
  ],
  'billingCheck'=>[
    'routingNumber'=>'123456789',
    'bankAccountNumber'=>'aBankToken123456',
    'accountDirective'=>'1111-1',
    'checkNumber'=>'12'
  ],
  'customReceiptLabels'=>[
    'PAYMENT'=>'Custom payment label',
    'ACCOUNT_NUMBER'=>'Custom account number label',
    'MEMO'=>'Custom memo label',
    'BANK_ACCOUNT_TYPE'=>'Custom account type label'
  ],
  'customRenderLabels'=>[
    'SCHEDULE_STATUS'=>'Custom schedule status label'
  ],
  'roundTripMap'=> [
    'myField1'=>'Custom Value 1',
    'myField2'=>'Custom Value 2'
  ],
  'notificationEvent'=>'SCHEDULE'
];


$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($schedule, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
    $authorization]
);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

    my $schedule = {
        'firstName'=>'Test',
        'lastName'=>'McTesty',
        'accountNumber'=>'123455',
        'owedAmount'=>'1000',
        'settingId'=>'2',
        'numberOfPayments'=>'',
        'paymentAmount'=>'100',
        'initialPaymentAmount'=>'',
        'adjustmentAmount'=>'',
        'username'=>'testUser',
        'paymentMethod'=>'CHECK',
        'phoneNumber'=>'',
        'status'=>'ACTIVE',
        'emailAddress'=>'test@test.com',
        'memo'=>'',
        'origin'=>'EXT',
        'recurrenceRule'=>'FREQ=MONTHLY;INTERVAL=1;',
        'sendReceiptToEmailAddress'=>'true',
        'sendAuthorizationRequest'=>'true',
        'requestPaymentData'=>'false',
        'authorization'=>{
            'pinDescription'=>'Last 4 of card number',
            'verificationPin'=>'1234',
            'timeoutMinutes'=>'30',
            'eventRecipientList'=>[
                {
                    'emailAddress'=>'someone@example.com'
                }
            ]
        },
        'billingCheck'=>{
            'routingNumber'=>'123456789',
            'bankAccountNumber'=>'aBankToken123456',
            'accountDirective'=>'1111-1',
            'checkNumber'=>'12'
        },
        'customReceiptLabels'=>{
            'PAYMENT'=>'Custom payment label',
            'ACCOUNT_NUMBER'=>'Custom account number label',
            'MEMO'=>'Custom memo label',
            'BANK_ACCOUNT_TYPE'=>'Custom account type label'
        },
        'customRenderLabels'=>{
            'SCHEDULE_STATUS'=>'Custom schedule status label'
        },
         'roundTripMap'=> {
            'myField1'=>'Custom Value 1',
            'myField2'=>'Custom Value 2'
        },
        'notificationEvent'=>'SCHEDULE'
    }

    $data = JSON::XS->new->utf8->encode ($schedule);
    my $url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules';

    my $req = HTTP::Request->new( 'POST', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    schedule = {
        'firstName'=>'Test',
        'lastName'=>'McTesty',
        'accountNumber'=>'123455',
        'owedAmount'=>'1000',
        'settingId'=>'2',
        'numberOfPayments'=>'',
        'paymentAmount'=>'100',
        'initialPaymentAmount'=>'',
        'adjustmentAmount'=>'',
        'username'=>'testUser',
        'paymentMethod'=>'CHECK',
        'phoneNumber'=>'',
        'status'=>'ACTIVE',
        'emailAddress'=>'test@test.com',
        'memo'=>'',
        'origin'=>'EXT',
        'recurrenceRule'=>'FREQ=MONTHLY;INTERVAL=1;',
        'sendReceiptToEmailAddress'=>'true',
        'sendAuthorizationRequest'=>'true',
        'requestPaymentData'=>'false',
        'authorization'=>{
            'pinDescription'=>'Last 4 of card number',
            'verificationPin'=>'1234',
            'timeoutMinutes'=>'30',
            'eventRecipientList'=>[
                {
                    'emailAddress'=>'someone@example.com'
                }
            ]
        },
        'billingCheck'=>{
            'routingNumber'=>'123456789',
            'bankAccountNumber'=>'aBankToken123456',
            'accountDirective'=>'1111-1',
            'checkNumber'=>'12'
        },
        'customReceiptLabels'=>{
            'PAYMENT'=>'Custom payment label',
            'ACCOUNT_NUMBER'=>'Custom account number label',
            'MEMO'=>'Custom memo label',
            'BANK_ACCOUNT_TYPE'=>'Custom account type label'
        },
        'customRenderLabels'=>{
            'SCHEDULE_STATUS'=>'Custom schedule status label'
        },
         'roundTripMap'=> {
            'myField1'=>'Custom Value 1',
            'myField2'=>'Custom Value 2'
        },
        'notificationEvent'=>'SCHEDULE'
    }

    c = Curl::Easy.new
    c.url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = schedule.to_json.length
    payload = schedule.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

This will create a Schedule with 10 CHECK payments of $100. As sendAuthorizationRequest is true, a signature request will be sent to the email “test@test.com” and the schedule will be in AUTHORIZE status until that signature is completed, upon which the schedule will automatically become ACTIVE.

Send an HTTP POST request to:
test url:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules
live url:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules

Sample Schedule Patch request

<?php
    $scheduleIdToPatch = 2;
    $url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/'.$scheduleIdToPatch;

    $authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');

    $schedulePatch = [
        'status' => 'ACTIVE',
        'firstName' => 'Test',
        'lastName' => 'Testing',
        'accountNumber' => '123455',
        'origin' => 'EXT',
        'username' => 'user',
        'memo' => '', //This will clear the current value of memo
        'emailAddress' => 'test@test.com',
        'phoneNumber' => '4654654654',
        'addressOne' => '', //This will clear the current value of addressOne
        'addressTwo' => '', //This will clear the current value of addressTwo
        'city' => 'Montezuma',
        'state' => 'MI',
        'zip' => '84404',
        'zipPlusFour' => '4564',
        'country' => 'US',
        'paymentMethod' => 'CARD',
        'billingCard' => [
            'cardToken' => 'aCardToken123456',
            'expirationMonth' => '12',
            'expirationYear' => '24',
            'accountDirective' => '1111'
        ],
        'customReceiptLabels'=>[
            'PAYMENT'=>'Custom payment label',
            'ACCOUNT_NUMBER'=>'Custom account number label',
            'MEMO'=>'Custom memo label',
            'BANK_ACCOUNT_TYPE'=>'Custom account type label'
        ],
        'customRenderLabels'=>[
            'SCHEDULE_STATUS'=>'Custom schedule status label'
        ],
        'roundTripMap'=> [
            'myField1'=>'Custom Value 1',
            'myField2'=>'Custom Value 2'
        ],
        'notificationEvent'=>'SCHEDULE'
    ];


    $curl = curl_init();

    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH');
    $data = json_encode($schedulePatch, JSON_UNESCAPED_SLASHES);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    curl_setopt($curl, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
                'Content-Length: ' . strlen($data),
                $authorization]
    );
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);  //num seconds to try connecting
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

    $result = curl_exec($curl);

    $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    // View response
    print_r(json_decode($result, true));

    if($statusCode == '200') {
      echo $result;
    }
    else {
      echo "Error #:" . $statusCode;
    }
    curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
    my $scheduleIdToPatch = 2;
    my $schedulePatch = {
        'status' => 'ACTIVE',
        'firstName' => 'Test',
        'lastName' => 'Testing',
        'accountNumber' => '123455',
        'origin' => 'EXT',
        'username' => 'user',
        'memo' => '', //This will clear the current value of memo
        'emailAddress' => 'test@test.com',
        'phoneNumber' => '4654654654',
        'addressOne' => '', //This will clear the current value of addressOne
        'addressTwo' => '', //This will clear the current value of addressTwo
        'city' => 'Montezuma',
        'state' => 'MI',
        'zip' => '84404',
        'zipPlusFour' => '4564',
        'country' => 'US',
        'paymentMethod' => 'CARD',
        'billingCard' => {
            'cardToken' => 'aCardToken123456',
            'expirationMonth' => '12',
            'expirationYear' => '24',
            'accountDirective' => '1111'
        },
        'customReceiptLabels'=>{
            'PAYMENT'=>'Custom payment label',
            'ACCOUNT_NUMBER'=>'Custom account number label',
            'MEMO'=>'Custom memo label',
            'BANK_ACCOUNT_TYPE'=>'Custom account type label'
        },
        'customRenderLabels'=>{
            'SCHEDULE_STATUS'=>'Custom schedule status label'
        },
         'roundTripMap'=> {
            'myField1'=>'Custom Value 1',
            'myField2'=>'Custom Value 2'
        },
        'notificationEvent'=>'SCHEDULE'
    }

    $data = JSON::XS->new->utf8->encode ($schedulePatch);
    my $url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/'.$scheduleIdToPatch;

    my $req = HTTP::Request->new( 'PATCH', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}

#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin
    scheduleIdToPatch = 2
    schedulePatch = {
        'status' => 'ACTIVE',
        'firstName' => 'Test',
        'lastName' => 'Testing',
        'accountNumber' => '123455',
        'origin' => 'EXT',
        'username' => 'user',
        'memo' => '', //This will clear the current value of memo
        'emailAddress' => 'test@test.com',
        'phoneNumber' => '4654654654',
        'addressOne' => '', //This will clear the current value of addressOne
        'addressTwo' => '', //This will clear the current value of addressTwo
        'city' => 'Montezuma',
        'state' => 'MI',
        'zip' => '84404',
        'zipPlusFour' => '4564',
        'country' => 'US',
        'paymentMethod' => 'CARD',
        'billingCard' => {
            'cardToken' => 'aCardToken123456',
            'expirationMonth' => '12',
            'expirationYear' => '24',
            'accountDirective' => '1111'
        },
        'customReceiptLabels'=>{
            'PAYMENT'=>'Custom payment label',
            'ACCOUNT_NUMBER'=>'Custom account number label',
            'MEMO'=>'Custom memo label',
            'BANK_ACCOUNT_TYPE'=>'Custom account type label'
        },
        'customRenderLabels'=>{
            'SCHEDULE_STATUS'=>'Custom schedule status label'
        },
         'roundTripMap'=> {
            'myField1'=>'Custom Value 1',
            'myField2'=>'Custom Value 2'
        },
        'notificationEvent'=>'SCHEDULE'
    }

    c = Curl::Easy.new
    c.url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/' + scheduleIdToPatch
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = schedulePatch.to_json.length
    payload = schedulePatch.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

This will update a Schedule. Parameters passed in empty will clear the previous value. If change on a field is undesired, do not pass in that parameter. The Schedule will be returned with the newly updated values.

Send an HTTP PATCH request to:
test url:
https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}
live url:
https://schedule.pdc4u.com/ScheduleService/api/v1_0/schedules/{scheduleId}

Sample Schedule Account Directive Migration

<?php
$url = 'https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/migrations/accountdirectives';

$authorization = "Authorization: BASIC " . base64_encode('companyUsername'.':'.'companyPassword');

$migrationRequest = [
  'oldAccountDirective' => '123-1',
  'newAccountDirective' => '123-2'
];

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, [
  'Content-Type: application/json',
  $authorization
]);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_PATCH, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, migrationRequest);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

   my $uri = URI->new("https://scheduledemo.pdc4u.com/ScheduleService/api/v1_0/migrations/accountdirectives");

   my $migrationRequest = {
      'oldAccountDirective' => '123-1',
      'newAccountDirective' => '123-2'
   }

   my $req = HTTP::Request->new( 'POST', $uri );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($migrationRequest) );
   $req->content( $migrationRequest );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};