using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Security.Cryptography;
///
/// Helper class to handle the payment integration with PayGate
///
///
public enum ProcessNowOptions { Yes, No };
public class PayGateSubscriptions
{
public string PayGate_ID
{ get; set; }
public string PayGate_Key
{ get; set; }
public string Reference
{ get; set; }
public float Amount
{ get; set; }
public string Currency
{ get; set; }
public string Return_URL
{ get; set; }
public string UserEmail
{ get; set; }
public ProcessNowOptions ProcessNow
{ get; set; }
public float ProcessNowAmount
{ get; set; }
public DateTime SubsStartDate
{ get; set; }
public DateTime SubsEndDate
{ get; set; }
//private static string PayGate_Server = "https://www.paygate.co.za/paywebv2/process.trans";
private static string PayGate_Server = "SendRequestSubs.aspx";
private static string PayGate_Version = "21";
/****************************************************************************************************/
///
/// Initializes a new instance of the class.
///
public PayGateSubscriptions()
{
PayGate_ID = System.Configuration.ConfigurationManager.AppSettings.Get("PayGate_ID");
PayGate_Key = System.Configuration.ConfigurationManager.AppSettings.Get("PayGate_Key");
Currency = System.Configuration.ConfigurationManager.AppSettings.Get("PayGate_Currency");
Return_URL = System.Configuration.ConfigurationManager.AppSettings.Get("PayGate_ReturnURL");
}
/****************************************************************************************************/
///
/// Initializes a new instance of the class.
///
/// The pay gate ID.
/// The pay gate encryption key.
/// The pay gate currency.
/// The pay gate return URL.
public PayGateSubscriptions(string PayGate_ID, string PayGate_Key, string PayGate_Currency, string PayGate_ReturnURL)
{
this.PayGate_ID = PayGate_ID;
this.PayGate_Key = PayGate_Key;
this.Currency = PayGate_Currency;
this.Return_URL = PayGate_ReturnURL;
}
/****************************************************************************************************/
///
/// Generates the PayGate MD5 checksum.
///
/// The data.
///
private string GenerateChecksum(string Data)
{
ASCIIEncoding AE = new ASCIIEncoding();
byte[] ByteSource = AE.GetBytes(Data);
MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
byte[] Hash = MD5.ComputeHash(ByteSource);
string Checksum = "";
for (int i = 0; i < Hash.Length; i++)
{
Checksum += Hash[i].ToString("x2").ToUpper();
}
return Checksum;
}
/****************************************************************************************************/
///
/// Starts the payment process.
///
public string StartPayment()
{
string TransDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
string TransAmnt = (Amount * 100).ToString("G0");
string NowAmnt = (ProcessNowAmount * 100).ToString("G0");
string Frequency = "201"; //Subs Frequency - set to 1st day of the month. See below.
string ChecksumSource = PayGate_Version + "|" + PayGate_ID + "|";
ChecksumSource += Reference + "|";
ChecksumSource += TransAmnt + "|";
ChecksumSource += Currency + "|";
ChecksumSource += Return_URL + "|";
ChecksumSource += TransDate + "|";
if (!string.IsNullOrEmpty(UserEmail))
ChecksumSource += UserEmail + "|";
ChecksumSource += SubsStartDate.ToString("yyyy-MM-dd") + "|";
ChecksumSource += SubsEndDate.ToString("yyyy-MM-dd") + "|";
ChecksumSource += Frequency + "|";
if (ProcessNow == ProcessNowOptions.Yes)
{
ChecksumSource += "YES|" + NowAmnt + "|";
}
else
{
ChecksumSource += "NO||";
}
ChecksumSource += PayGate_Key;
string Checksum = GenerateChecksum(ChecksumSource);
string PostUrl = PayGate_Server + "?";
PostUrl += "VERSION=" + PayGate_Version;
PostUrl += "&PAYGATE_ID=" + PayGate_ID;
PostUrl += "&REFERENCE=" + Reference;
PostUrl += "&AMOUNT=" + TransAmnt;
PostUrl += "&CURRENCY=" + Currency;
PostUrl += "&TRANSACTION_DATE=" + TransDate;
PostUrl += "&SUBS_START_DATE=" + SubsStartDate.ToString("yyyy-MM-dd");
PostUrl += "&SUBS_END_DATE=" + SubsEndDate.ToString("yyyy-MM-dd");
PostUrl += "&SUBS_FREQUENCY=" + Frequency;
if (ProcessNow == ProcessNowOptions.Yes)
{
PostUrl += "&PROCESS_NOW=YES";
PostUrl += "&PROCESS_NOW_AMOUNT=" + NowAmnt;
}
else
{
PostUrl += "&PROCESS_NOW=NO";
PostUrl += "&PROCESS_NOW_AMOUNT=";
}
PostUrl += "&RETURN_URL=" + Return_URL;
if (!string.IsNullOrEmpty(UserEmail))
PostUrl += "&EMAIL=" + UserEmail;
PostUrl += "&CHECKSUM=" + Checksum;
return PostUrl;
}
/****************************************************************************************************/
///
/// Confirms the checksum result.
///
/// The rx amount.
/// The transaction_ status.
/// The result_ code.
/// The result_ desc.
/// The auth_ code.
/// The transaction_ id.
/// The risk_ indicator.
/// The checksum.
///
public bool ConfirmChecksumResult(string rxAmount, string Transaction_Status, string Result_Code, string Result_Desc, string Auth_Code, string Transaction_Id, string Subscription_Id, string Risk_Indicator, string rxChecksum)
{
bool result = false;
string ChecksumSource = PayGate_ID + "|";
ChecksumSource += Reference + "|";
ChecksumSource += Transaction_Status + "|";
ChecksumSource += Result_Code + "|";
ChecksumSource += Auth_Code + "|";
ChecksumSource += rxAmount + "|";
ChecksumSource += Result_Desc + "|";
ChecksumSource += Transaction_Id + "|";
ChecksumSource += Subscription_Id + "|";
if (!string.IsNullOrEmpty(Risk_Indicator))
ChecksumSource += Risk_Indicator + "|";
ChecksumSource += PayGate_Key;
result = rxChecksum.ToUpper().Equals(GenerateChecksum(ChecksumSource));
return result;
}
/****************************************************************************************************/
public string GetChecksumResult(string rxAmount, string Transaction_Status, string Result_Code, string Result_Desc, string Auth_Code, string Transaction_Id, string Subscription_Id, string Risk_Indicator, string rxChecksum)
{
string result = "";
string ChecksumSource = PayGate_ID + "|";
ChecksumSource += Reference + "|";
ChecksumSource += Transaction_Status + "|";
ChecksumSource += Result_Code + "|";
ChecksumSource += Auth_Code + "|";
ChecksumSource += rxAmount + "|";
ChecksumSource += Result_Desc + "|";
ChecksumSource += Transaction_Id + "|";
ChecksumSource += Subscription_Id + "|";
if (!string.IsNullOrEmpty(Risk_Indicator))
ChecksumSource += Risk_Indicator + "|";
ChecksumSource += PayGate_Key;
result = GenerateChecksum(ChecksumSource);
return result;
}
/****************************************************************************************************/
///
/// Gets the transaction status.
///
/// The status.
///
public string GetTransactionStatus(int Status)
{
string result = "";
switch (Status)
{
case 0:
result = "Pending";
break;
case 1:
result = "Approved";
break;
case 2:
result = "Declined";
break;
}
return result;
}
/****************************************************************************************************/
///
/// Gets the result code.
///
/// The code.
///
public string GetResultCode(int Code)
{
string result = "";
switch (Code)
{
case 0:
result = "N/A";
break;
case 990017:
result = "Approved Transaction";
break;
case 900003:
result = "Insufficient Funds";
break;
case 900007:
result = "Declined Transaction";
break;
case 900004:
result = "Invalid Card Number";
break;
case 990022:
result = "Unprocessed Transaction";
break;
}
return result;
}
/****************************************************************************************************/
///
/// Gets the risk indicator.
///
/// The status.
///
public string GetRiskIndicator(string Status)
{
string result = "";
switch (Status.ToUpper())
{
case "AX":
result = "Authenticated";
break;
case "NX":
result = "Not Authenticated";
break;
default:
result = "N/A";
break;
}
return result;
}
/****************************************************************************************************/
///
/// Return the results code as a status code.
///
/// The code.
///
public int ResultCodeAsStatus(int Code)
{
int result = 0;
switch (Code)
{
case 0:
result = (int)PaymentResults.Pending;
break;
case 990017:
result = (int)PaymentResults.Approved;
break;
case 900003:
result = (int)PaymentResults.InsufficientFunds;
break;
case 900007:
result = (int)PaymentResults.Declined;
break;
case 900004:
result = (int)PaymentResults.InvalidCard;
break;
case 990022:
result = (int)PaymentResults.Pending;
break;
}
return result;
}
/****************************************************************************************************/
/* Subscription Frequency Codes */
/*
Code Description
111 Weekly on Sun
112 Weekly on Mon
113 Weekly on Tue
114 Weekly on Wed
115 Weekly on Thu
116 Weekly on Fri
117 Weekly on Sat
121 2nd Weekly on Sun
122 2nd Weekly on Mon
123 2nd Weekly on Tue
124 2nd Weekly on Wed
125 2nd Weekly on Thu
126 2nd Weekly on Fri
127 2nd Weekly on Sat
131 3rd Weekly on Sun
132 3rd Weekly on Mon
133 3rd Weekly on Tue
134 3rd Weekly on Wed
135 3rd Weekly on Thu
136 3rd Weekly on Fri
137 3rd Weekly on Sat
201 Monthly on 1st
202 Monthly on 2nd
203 Monthly on 3rd
204 Monthly on 4th
205 Monthly on 5th
206 – 227 as above
228 Monthly on 28th
229 Last day of the month
301 – 328 Every 2nd month on 1st to 28th respectively
329 Every 2nd month on last day of the month
401 – 428 Every 3rd month on 1st to 28th respectively
429 Every 3rd month on last day of the month
*/
/****************************************************************************************************/
/*
Card Brand Card Number Risk Indicator
Approved Transactions. RESULT_CODE = 990017; TRANSACTION_STATUS = 1.
Visa 4000000000000002 Authenticated (AX) *
MasterCard 5200000000000015 Authenticated (AX)
American Express 378282246310005 Not Authenticated (NX)
FNB Cell Pay Point N/A; enter MR PASS
in Account Holder
field.
Authenticated (AX)
Mobux 6397729999003950 Not Applicable (XX)
Ukash Voucher
(with new voucher issued as change)
9999991500000000012 Authenticated (AX)
Ukash Voucher
(with no change voucher issued)
9999991500000000020 Authenticated (AX)
Ukash Card 9826160000000005 Authenticated (AX)
Insufficient Funds Transactions. RESULT_CODE = 900003; TRANSACTION_STATUS = 2.
MasterCard 5200000000000023 Not Authenticated (NX) *
Visa 4000000000000028 Not Authenticated (NX)
American Express 371449635398431 Not Authenticated (NX)
Declined Transactions. RESULT_CODE = 900007; TRANSACTION_STATUS = 2.
Visa 4000000000000036 Authenticated (AX) *
MasterCard 5200000000000049 Authenticated (AX) *
Diners Club 30569309025904 Not Applicable (XX)
FNB Cell Pay Point N/A; enter MR FAIL in
Account Holder field.
Not Applicable (XX)
Mobux 6397729999003550 Not Applicable (XX)
Ukash Voucher 9999991500000000038 Not Applicable (XX)
Ukash Card 9826160000000013 Not Applicable (XX)
Invalid Card Number. RESULT_CODE = 900004; TRANSACTION_STATUS = 2.
All other card numbers Not Applicable (XX)
Unprocessed Transactions. RESUT_CODE = 990022; TRANSACTION_STATUS = 0.
MasterCard 5200000000000064 Not Applicable (XX)
Expiry Date must be in the future; Card Holder & CVV or Ukash PIN can be made up.
* = Using these card numbers will allow you to test the MasterCard SecureCode / Verified-by-Visa
authentication process.
The default test account does not allow any customisation; all options are enabled and there is no logo.
*/
}