using System.Security.Cryptography;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
public static void Main()
string url = "https://sb-billpayments.cbwpayments.com/CEDirectoryServer/rest/billPayApi/billPay";
""apiKey"": ""d2412ca375835f4aa0c13492f309711e24faf40da1a4382ee86e14b95ec00c62"",
""reference"": ""REF50012""
""tspCustomerId"": ""165206412820975"",
""transactionType"": ""PAYMENT"",
""transactionDateTime"": ""12345678901234"",
""program"": ""BILL_PAY"",
""batchNumber"": ""2019021203""
""transactionNumber"": ""201902120005"",
""customerType"": ""TEST"",
""customerAccountNumber"": ""L01625199"",
""clientNumber"": ""ABC"",
""clientNumberType"": ""ABC"",
""lastName"": ""Millan"",
""cbwSettlementAccountNumber"": ""200231015876170"",
""cbwChannelPartnerName"": ""cascade"",
""cbwChannelPartnerId"": ""165206412820975""
""billerName"": ""100 CAPTAINS ROW"",
""billerIdNumber"": ""55383445679""
""otherRequestSource"": """",
""purpose"": ""CREDIT CARD"",
""key"": ""<STRING_USED_TO_SIGN>""
using JsonDocument doc = JsonDocument.Parse(jsonreq);
JsonElement root = doc.RootElement;
JsonElement arr = root.GetProperty("transactions");
string apiKey = root.GetProperty("api").GetProperty("apiKey").GetString();
string tspCustomerId = root.GetProperty("tspCustomerId").GetString();
string batchNumber = root.GetProperty("batchDetails").GetProperty("batchNumber").GetString();
string customerAccountNumber = arr[0].GetProperty("customer").GetProperty("customerAccountNumber").GetString();
string cbwSettlementAccountNumber = arr[0].GetProperty("channelPartner").GetProperty("cbwSettlementAccountNumber").GetString();
string cbwChannelPartnerId = arr[0].GetProperty("channelPartner").GetProperty("cbwChannelPartnerId").GetString();
string billerIdNumber = arr[0].GetProperty("destination").GetProperty("biller").GetProperty("billerIdNumber").GetString();
string amount = arr[0].GetProperty("amount").GetString()+"00";
string fieldToSigns = apiKey+tspCustomerId+batchNumber+customerAccountNumber+cbwSettlementAccountNumber+cbwChannelPartnerId+billerIdNumber+amount;
dynamic obj = JObject.Parse(jsonreq);
var val = obj["transactions"][0];
string option = (string)val["signature"];
string signedPayload = Sign(fieldToSigns);
val["signature"] = signedPayload;
string result = obj.ToString();
StringContent postContent = new StringContent(result, Encoding.UTF8, "application/json");
HttpClient ServiceClient = new HttpClient();
var byteArray = Encoding.ASCII.GetBytes("billpayments:Wb4LEeeBK7VI57!");
ServiceClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
HttpResponseMessage response = ServiceClient.PostAsync(url, postContent).Result;
string rs = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(Environment.NewLine + "Response:" + Environment.NewLine + rs);
static string Sign(string payloadJson)
string privKey = @"-----BEGIN PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCAYfwEB+C8E8JQ+jRZS
KVE3wzXDEj51rkfPLbTq4S55DQ==
-----END PRIVATE KEY-----";
var key = ECDsa.Create();
key.ImportFromPem(privKey);
byte[] rawSig = key.SignData(System.Text.Encoding.UTF8.GetBytes(payloadJson), HashAlgorithmName.SHA1);
return DEREncoder.Encode(rawSig);
public static string Encode(byte[] rawSign)
int halfLength = rawSign.Length / 2;
byte[][] rEncoded = SegmentedEncodeUnsignedInteger(rawSign, 0, halfLength);
byte[][] sEncoded = SegmentedEncodeUnsignedInteger(rawSign, halfLength, halfLength);
List<byte[][]> items = new List<byte[][]>()
byte[] opensslSig = ConstructSequence(items);
return System.Convert.ToBase64String(opensslSig);
internal static byte[][] SegmentedEncodeUnsignedInteger(byte[] bigEndianBytes, int offset, int count)
int num = srcOffset + count;
while (srcOffset < num && (int)bigEndianBytes[srcOffset] == 0)
int count1 = num - srcOffset;
if ((int)bigEndianBytes[srcOffset] > (int)sbyte.MaxValue)
dataBytes = new byte[count1 + 1];
dataBytes = new byte[count1];
System.Buffer.BlockCopy(bigEndianBytes, srcOffset, dataBytes, dstOffset, count1);
return new[]{new[]{(byte)0x02}, EncodeLength(dataBytes.Length), dataBytes, };
internal static byte[] ConstructSequence(IEnumerable<byte[][]> items)
foreach (byte[][] segments in items)
foreach (byte[] segment in segments)
payloadLength += segment.Length;
byte[] encodedLength = EncodeLength(payloadLength);
byte[] encodedSequence = new byte[1 + encodedLength.Length + payloadLength];
encodedSequence[0] = 0x20 | 0x10;
Buffer.BlockCopy(encodedLength, 0, encodedSequence, writeStart, encodedLength.Length);
writeStart += encodedLength.Length;
foreach (byte[][] segments in items)
foreach (byte[] segment in segments)
Buffer.BlockCopy(segment, 0, encodedSequence, writeStart, segment.Length);
writeStart += segment.Length;
private static byte[] EncodeLength(int length)
byte low = unchecked((byte)length);
return new byte[]{0x81, low};
int remainder = length >> 8;
byte midLow = unchecked((byte)remainder);
return new byte[]{0x82, midLow, low};
byte midHigh = unchecked((byte)remainder);
return new byte[]{0x83, midHigh, midLow, low};
byte high = unchecked((byte)remainder);
return new byte[]{0x84, high, midHigh, midLow, low};