|
/// <summary> |
|
/// Generate an XML document containing a SEPA Credit Transfer (SCT) |
|
/// </summary> |
|
/// <param name="refunds">Collection of refunds from the debtor (a company) to the creditor (a customer)</param> |
|
/// <returns>XML document</returns> |
|
private XDocument GenerateXMLFile(IEnumerable<RefundObject> refunds) |
|
{ |
|
XDocument document = null; |
|
|
|
// Get the correct namespace to build the Pain 001.001.03 document |
|
XNamespace xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); |
|
XNamespace xmlns = "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"; |
|
|
|
// The namespace needs to prefix all the element names down the tree. There is no "inheritance" of namespace in XML, therefore |
|
// use this anonymous function to concatenate namespace and element name. |
|
// On the long run, it makes the code (a little) more readable. |
|
// For example: |
|
// new XElement(ns("CreDtTm"), DateTime.Now.ToString("yyyy-MM-ddThh:mm:ss")), |
|
// instead of |
|
// new XElement(xmlns + "CreDtTm", DateTime.Now.ToString("yyyy-MM-ddThh:mm:ss")), |
|
Func<string, XName> ns = elementName => xmlns + elementName; |
|
|
|
// get the payment details elements to add in the tree |
|
var paymentDetails = this.GetPaymentDetails(refunds, ns); |
|
|
|
document = new XDocument(new XDeclaration("1.0", Encoding.UTF8.BodyName, "yes"), |
|
new XElement(ns("Document"), |
|
new XAttribute(XNamespace.Xmlns + "xsi", xsi), |
|
new XElement(ns("CstmrCdtTrfInitn"), |
|
|
|
// Group Header |
|
new XElement(ns("GrpHdr"), |
|
new XElement(ns("MsgId"), ["Generate_Unique_ID"]), |
|
new XElement(ns("CreDtTm"), DateTime.Now.ToString("yyyy-MM-ddThh:mm:ss")), |
|
new XElement(ns("NbOfTxs"), refunds.Count()), |
|
new XElement(ns("CtrlSum"), refunds.Sum(x => x.Amount).ToString("#0.00", CultureInfo.InvariantCulture)), |
|
new XElement(ns("InitgPty"), |
|
new XElement(ns("Nm"), "[Name_Of_Initiating_Party]")) |
|
|
|
), // group header |
|
|
|
// add all the payment elements |
|
paymentDetails.ToArray() |
|
|
|
) // CstmrCdtTrfInitn |
|
) // Document xmlns |
|
); |
|
|
|
return document; |
|
} |
|
|
|
/// <summary> |
|
/// Get the batch of payments to the creditors |
|
/// </summary> |
|
/// <param name="refunds">Collection of refunds</param> |
|
/// <param name="ns">Delegate method to concatenate the namespace with the element name</param> |
|
/// <returns>XML formatted payment batches</returns> |
|
private IEnumerable<XElement> GetPaymentDetails(IEnumerable<RefundObject> refunds, Func<string, XName> ns) |
|
{ |
|
List<XElement> xelements = new List<XElement>(); |
|
|
|
foreach (var refund in refunds) |
|
{ |
|
// format the data before |
|
var endtoendid = refund.EndToEndId.HasValue ? refund.EndToEndId : "NOTPROVIDED"; |
|
|
|
// add the refund info in the file |
|
xelements.Add(new XElement(ns("PmtInf"), |
|
new XElement(ns("PmtInfId"), refund.Id), |
|
new XElement(ns("PmtMtd"), "TRF"), // Payment method => always TRF = transfer |
|
new XElement(ns("BtchBookg"), "true"), // True => bulk posting, False => single posting |
|
new XElement(ns("NbOfTxs"), 1), |
|
new XElement(ns("CtrlSum"), refund.Amount), |
|
new XElement(ns("PmtTpInf"), |
|
new XElement(ns("SvcLvl"), |
|
new XElement(ns("Cd"), "SEPA"))), // Payment Type Info => SEPA |
|
new XElement(ns("ReqdExctnDt"), DateTime.Now.ToString("yyyy-MM-dd")), // Requested execution date |
|
new XElement(ns("Dbtr"), |
|
new XElement(ns("Nm"), "[Debtor_Name]")), |
|
new XElement(ns("DbtrAcct"), |
|
new XElement(ns("Id"), |
|
new XElement(ns("IBAN"), "[Debtor_IBAN]"))), |
|
new XElement(ns("DbtrAgt"), |
|
new XElement(ns("FinInstnId"), |
|
new XElement(ns("BIC"), "[Debtor_BIC]"))), |
|
new XElement(ns("ChrgBr"), "SLEV"), // Charge bearer => always "SLEV" in SEPA = share |
|
|
|
new XElement(ns("CdtTrfTxInf"), |
|
new XElement(ns("PmtId"), |
|
new XElement(ns("EndToEndId"), endtoendid)), |
|
new XElement(ns("Amt"), |
|
new XElement(ns("InstdAmt"), |
|
new XAttribute("Ccy", "EUR"), refund.Amount)), // EUR |
|
new XElement(ns("CdtrAgt"), |
|
new XElement(ns("FinInstnId"), |
|
new XElement(ns("BIC"), "[Creditor_BIC]"))), |
|
new XElement(ns("Cdtr"), |
|
new XElement(ns("Nm"), "[Creditor_Name]")), |
|
new XElement(ns("CdtrAcct"), |
|
new XElement(ns("Id"), |
|
new XElement(ns("IBAN"), "[Creditor_IBAN]"))), |
|
new XElement(ns("RmtInf"), |
|
new XElement(ns("Ustrd"), "[Remittance information]")) // 140 char max |
|
) // CdtTrfTxInf |
|
)); // PmtInf |
|
} |
|
|
|
return xelements; |
|
} |