@ariejones/propay-sdk
v1.0.2
Published
TypeScript SDK for ProPay SPI integration
Readme
ProPay SDK
TypeScript SDK for ProPay SPI (Secure Payment Interface) integration. This library provides a simple interface for handling ProPay temporary tokens, encryption, and decryption of SPI responses.
⚠️ Server-Side Only
This SDK can only be used in server-side environments. It requires Node.js APIs (crypto, Buffer) that are not available in browsers. The SDK will throw an error if instantiated in a browser environment.
Supported Environments
- ✅ Node.js applications
- ✅ Next.js API routes
- ✅ Next.js Server Components
- ✅ Next.js Server Actions
- ✅ Express.js routes
- ✅ Other Node.js server frameworks
Not Supported
- ❌ Browser/client-side code
- ❌ React Client Components (use Server Actions or API routes instead)
- ❌ Browser-based bundlers that target the browser
Installation
npm install @ariejones/propay-sdkUsage
Complete Example
Here's a complete example showing the full workflow:
import { ProPaySDK } from "@ariejones/propay-sdk";
async function example() {
// Initialize the SDK
const sdk = new ProPaySDK({
profileId: "your-profile-id",
primaryAccountNumber: "your-account-number",
environment: "test", // or 'prod'
certString: "your-cert-string",
termId: "your-term-id",
});
try {
// Step 1: Get a temporary token (you'll need to obtain this from your backend/ProPay)
// Note: createTempToken is a private method. You should obtain temp tokens through
// your backend service that has access to ProPay API credentials.
const tempToken = "your-temp-token-here"; // Obtain from your backend
// Step 2: Encrypt payment data using the temp token
const paymentData =
"Action=Store&CardNumber=4111111111111111&ExpireDate=1225&CVV2=123";
const encrypted = sdk.encrypt(tempToken, paymentData);
console.log("Encrypted Data:", encrypted);
// Step 3: Create settings cipher for SPI configuration
// This method creates a temp token internally and encrypts the settings
const { tempToken, encryptedSettings } = await sdk.createSettingsCipher({
payerId: 123456,
paymentProcessType: "CreditCard",
processMethod: "Always",
paymentMethodStorageOption: "Capture",
currencyCode: "USD", // Optional, defaults to "USD"
amount: 100.0,
invoiceNumber: "INV-001",
returnUrl: "https://yourapp.com/return",
});
console.log("Temp Token:", tempToken);
console.log("Settings Cipher:", encryptedSettings);
// Step 4: After receiving encrypted response from ProPay SPI, process it
// Use the tempToken returned from createSettingsCipher to decrypt the response
const encryptedResponse = "base64-encrypted-response-from-propay";
// Option 1: Just decrypt (returns data even if errors exist)
const decrypted = sdk.decryptResponse(tempToken, encryptedResponse);
console.log("Decrypted Response:");
console.log(" Payer ID:", decrypted.PayerId);
console.log(" Payment Method ID:", decrypted.PaymentMethodId);
// Option 2: Process and validate (throws error if response contains errors)
try {
const processed = sdk.processSpiResponse(tempToken, encryptedResponse);
console.log("Processed Response (no errors):", processed);
} catch (error) {
console.error(
"SPI Response Error:",
error instanceof Error ? error.message : String(error)
);
}
} catch (error) {
console.error(
"Error:",
error instanceof Error ? error.message : String(error)
);
}
}Basic Setup
import { ProPaySDK } from "@ariejones/propay-sdk";
// Create SDK instance
const sdk = new ProPaySDK({
profileId: "your-profile-id",
primaryAccountNumber: "your-account-number",
environment: "test", // or 'prod'
certString: "your-cert-string",
termId: "your-term-id",
});Encrypting Data
// Encrypt content using the temporary token
// Note: You'll need to obtain the temp token from your backend service
const tempToken = "your-temp-token-here"; // Obtain from your backend
const content = "Action=Store&CardNumber=4111111111111111&ExpireDate=1225";
const encrypted = sdk.encrypt(tempToken, content);
console.log("Encrypted:", encrypted);Creating Settings Cipher
// Create encrypted settings cipher for SPI configuration
// This method creates a temp token internally and encrypts the settings
const { tempToken, encryptedSettings } = await sdk.createSettingsCipher({
payerId: 123456,
paymentProcessType: "CreditCard",
processMethod: "Always",
paymentMethodStorageOption: "Capture",
currencyCode: "USD", // Optional, defaults to "USD"
amount: 100.0,
invoiceNumber: "INV-001",
returnUrl: "https://yourapp.com/return",
});
console.log("Temp Token:", tempToken);
console.log("Settings Cipher:", encryptedSettings);Decrypting SPI Response
// Decrypt response from ProPay SPI (returns data even if errors exist)
const tempToken = "your-temp-token-here"; // Obtain from your backend
const decrypted = sdk.decryptResponse(tempToken, encryptedMessage);
console.log("Payer ID:", decrypted.PayerId);
console.log("Payment Method ID:", decrypted.PaymentMethodId);Processing SPI Response
// Process and validate SPI response (throws error if response contains errors)
const tempToken = "your-temp-token-here"; // Obtain from your backend
try {
const processed = sdk.processSpiResponse(tempToken, encryptedMessage);
console.log("Successfully processed:", processed);
} catch (error) {
console.error("SPI Response Error:", error.message);
}API Reference
ProPaySDK
Main SDK class for ProPay SPI operations.
Constructor
new ProPaySDK(config: ProPaySDKConfig)Parameters:
config.profileId(string): Your ProPay profile IDconfig.primaryAccountNumber(string): Your primary account numberconfig.environment('test' | 'prod'): Environment to useconfig.certString(string): Certification stringconfig.termId(string): Terminal ID
Methods
decryptResponse(token: string, encryptedMessage: string): SPIData
Decrypts encrypted SPI response from ProPay. Returns the decrypted data even if errors are present.
Parameters:
token(string): Temporary token used for encryptionencryptedMessage(string): Base64 encoded encrypted message
Returns: Decrypted SPIData object
processSpiResponse(token: string, encryptedMessage: string): SPIData
Processes and validates an encrypted SPI response from ProPay. Throws an error if the response contains any errors.
Parameters:
token(string): Temporary token used for encryptionencryptedMessage(string): Base64 encoded encrypted message
Returns: Decrypted and validated SPIData object
Throws: Error if the response contains ErrCode, StoreErrCode, or ProcErrCode
createSettingsCipher(options: CreateSettingsCipherOptions): Promise<CreateSettingsCipherResult>
Creates a settings cipher (encrypted string) for SPI configuration. This method creates a temporary token internally and uses it to encrypt the settings.
Parameters:
options.payerId(number): Payer ID for the transactionoptions.paymentProcessType('ACH' | 'CreditCard'): Type of payment processingoptions.processMethod('Always' | 'None' | 'OnSuccess'): Processing methodoptions.paymentMethodStorageOption('None' | 'Capture' | 'AuthOnly'): Storage option for payment methodoptions.currencyCode(string, optional): Currency code, defaults to "USD"options.amount(number): Transaction amountoptions.invoiceNumber(string): Invoice number for the transactionoptions.returnUrl(string): URL to return to after payment processingoptions.durationSeconds(string, optional): Duration for the temporary token in seconds, defaults to "3600" (1 hour)
Returns: Promise resolving to an object containing:
tempToken(string): The temporary token used for encryptionencryptedSettings(string): Base64 encoded encrypted settings string
Throws: Error if required parameters are missing or if temporary token creation fails
getEndpoints(): Readonly<ProPayEndpoints>
Gets all ProPay endpoints for the current environment.
Returns: Readonly object containing all endpoint URIs
getSpiUrl(): string
Gets the SPI (Secure Payment Interface) URL.
Returns: SPI endpoint URL
getRestBaseUri(): string
Gets the ProtectPay REST API base URI.
Returns: REST API base URI
getSoapUri(): string
Gets the ProtectPay SOAP URI.
Returns: SOAP endpoint URI
getWsdlUri(): string
Gets the ProtectPay WSDL URI.
Returns: WSDL endpoint URI
getWsdlSingleFileUri(): string
Gets the ProtectPay WSDL single file URI.
Returns: WSDL single file endpoint URI
Types
SPIData
Decrypted SPI response data structure containing payment method and transaction information.
CreateTempTokenResult
Temporary token result from ProPay containing:
tempToken: Temporary token for SPI operationspayerId: Payer ID associated with the tokencredentialId: Credential IDprimaryBillingProfileId: Primary billing profile IDpracticeProfileId: Practice profile ID
CreateSettingsCipherOptions
Options for creating a settings cipher:
payerId(number): Payer ID for the transactionpaymentProcessType('ACH' | 'CreditCard'): Type of payment processingprocessMethod('Always' | 'None' | 'OnSuccess'): Processing methodpaymentMethodStorageOption('None' | 'Capture' | 'AuthOnly'): Storage option for payment methodcurrencyCode(string, optional): Currency code, defaults to "USD"amount(number): Transaction amountinvoiceNumber(string): Invoice number for the transactionreturnUrl(string): URL to return to after payment processingdurationSeconds(string, optional): Duration for the temporary token in seconds, defaults to "3600"
CreateSettingsCipherResult
Result from creating a settings cipher:
tempToken(string): The temporary token used for encryptionencryptedSettings(string): Base64 encoded encrypted settings string
Environment Configuration
The SDK automatically configures all ProPay endpoints based on the environment:
Test/Integration Environment
- XML API:
https://xmltest.propay.com/API/PropayAPI.aspx - SPI URL:
https://protectpaytest.propay.com/pmi/spr.aspx - REST Base:
https://xmltestapi.propay.com/protectpay - SOAP:
https://xmltestapi.propay.com/protectpay/sps.svc - WSDL:
https://xmltestapi.propay.com/protectpay/sps.svc?wsdl
Production Environment
- XML API:
https://epay.propay.com/API/PropayAPI.aspx - SPI URL:
https://protectpay.propay.com/pmi/spr.aspx - REST Base:
https://api.propay.com/protectpay - SOAP:
https://api.propay.com/protectpay/sps.svc - WSDL:
https://api.propay.com/protectpay/sps.svc?wsdl
All endpoints are accessible via the SDK instance methods (e.g., sdk.getSpiUrl(), sdk.getRestBaseUri()).
Error Handling
All methods throw errors with descriptive messages. Always wrap SDK calls in try-catch blocks:
try {
const encrypted = sdk.encrypt(tempToken, content);
} catch (error) {
console.error("Encryption failed:", error.message);
}License
MIT
