T_LVL23CMP - Capture with Level II and III Data


// Example Program: T_LVL23CMP // Description: // This is a test program to illustrate how to call the CTI_Run() // subprocedure to perform a capture utilizing Level II and Level III // data used/required by FDC Compass. This program demonstrates // a request for Visa that matches the example on page 54 in the // LVL2/3 SO API guide provided by CyberSource: // http://goo.gl/4VZRIF // // Fields not used in this request but which may be used by others // (especially by MasterCard) are commented out. // // Note that this example relies on a previous authorization. // // To achieve this, generate a unique ID with CTI_NextUniqueId(), and // then populate and write a record to CTIWSHDR. This example also // writes one or more records to CTIWSITM to provide that level of // detail. Then, call CTI_Run() passing in your unique ID as well // as the other parameters shown. // // CTI_Run() will return *On if no error was encountered, or *Off // if an error occurred. If an error occurred, you should look at // the fields in ErrorDS to retrieve information about the error. // // Otherwise, you can perform a CHAIN against the CTIWSRSP physical // file, and retrieve the result fields. Ctl-Opt ActGrp(*Caller) BndDir('CTIBND') Option(*NoDebugIO); Dcl-F CTIWSHDR Disk(*Ext) Keyed Qualified Usage(*Input:*Output); Dcl-F CTIWSITM Disk(*Ext) Keyed Qualified Usage(*Input:*Output); Dcl-F CTIWSRSP Disk(*Ext) Keyed Qualified Usage(*Input); Dcl-Ds HDR ExtName('CTIWSHDR':*Output) Qualified End-Ds; Dcl-Ds ITM ExtName('CTIWSITM':*Output) Qualified End-Ds; Dcl-Ds RSP ExtName('CTIWSRSP':*Input) Qualified End-Ds; /COPY QRPGLECPY,CTICB // This is included for demo output purposes. Dcl-Pr WriteToJobLog Int(10) Extproc('Qp0zLprintf'); pString Pointer Value Options(*String); End-Pr; Dcl-C NewLine x'15'; // This stores the unique ID for this API call Dcl-S UniqueId Like(CTI_UniqueId_t) Inz; // This holds any error information returned by the API call Dcl-Ds ErrorDS LikeDS(CTI_ErrorDS_t) Inz(*LikeDS); // Modify this field to specify different card details Dcl-S CardNumber Char(20) Inz('4111111111111111'); // Modify this field to use your merchant ID Dcl-S MerchantId Like(CTI_MerchantId_t) Inz('ikrengel'); // This data structure is used to store details from the point of sale // payment terminal Dcl-Ds PosDS LikeDS(CTI_PosDS_t) Inz(*LikeDS); reset ErrorDS; // Each API call requires a unique ID UniqueId = CTI_NextUniqueId(); // Note that CTIWSHDR and CTIWSITM need to be occupied with the // necessary information first before running this request clear HDR; HDR.UID = UniqueId; HDR.CRTDT = %Timestamp(); HDR.CAPRUN = CTi_TRUE; HDR.MCHID = MerchantId; HDR.MCHREFCD = 'MYREFCD132'; HDR.CAPPCHLVL = '3'; // ID from previous authorization HDR.ATHREQID = '4351671320145000001518'; // required for Visa & MasterCard for best rate // valid formats are: #####, #####-#### (dash required), or // ### ### in CA // If customer takes possession of items at your location, should // match HDR.SFPSTCD HDR.STPSTCD = '56001'; // required for best rate in Visa, optional but recommended for // MasterCard HDR.STCNTRY = 'US'; HDR.STSTT = 'MN'; HDR.PTCUR = 'USD'; HDR.PTGNDAMT = '919.04'; // This is used if you're sending AMEX (and setting HDR.CCRDTYP to 003) // and if this is a capture // Otherwise, if this is a credit request it's not required, but you // would need to be populating HDR.CRDREQID //HDR.AMEXTAA1 = 'describe transaction'; // listed as required for all card types for // "purchase/procurement cards", but is otherwise listed as optional //HDR.USRPO = 'purchase order number'; // listed as optional for MasterCard, no details for other types //HDR.ALTTAXAMT = ''; // This is required if you set HDR.ALTTAXAMT to any value, including 0. // You can also send this without setting HDR.ALTTAXAMT //HDR.ALTTAXID = ''; // listed as optional for Visa, no details for other types //HDR.VATTAXAMT = ''; // listed as optional for Visa, no details for other types // describes the rate of VAT or other taxes for order // valid range is 0.01 to 0.99 (e.g. 1% to 99%) //HDR.VATTAXRTE = ''; // listed as optional for Visa, no details for other types // total discount applied to order //HDR.PTDSCAMT = ''; // listed as optional for Visa and MasterCard, no details for other // types // total charges for any import/export duties in order //HDR.PTDTYAMT = ''; // listed as optional for Visa and MasterCard, no details for other // types // total freight or shipping/handling charges for order. when this // is set, HDR.PTGNDAMT must also be set //HDR.PTFGTAMT = ''; // optional for Visa, required for MasterCard for best rate // valid formats are: #####, #####-#### (dash required), or // ### ### in CA //HDR.SFPSTCD = ''; write CTIWSHDR.CTIWSHDRR HDR; clear ITM; ITM.PID = UniqueId; ITM.UID = CTI_NextUniqueId(); ITM.CRTDT = %Timestamp(); // requied for Visa & MasterCard for Level III interchange // do not use all zeroes or spaces // text description of item ITM.PRDNAM = 'File Cabinet'; // Optional for Visa, not listed for other card types //ITM.COMMCD = ''; // required for Visa & MasterCard for Level III interchange // do not use all zeroes or spaces // if you don't provide this, CyberSource sets to 'default' ITM.PRDCD = 'default'; // required for Visa & MasterCard for Level III interchange // do not use all zeroes or spaces // must be a whole number ITM.QTY = 10; // required for all card types // unit cost of item purchased ITM.UNTPRC = '59.95'; // required for all card types // total tax to apply to product, cannot be negative ITM.TAXAMT = '49.46'; // required for all card types for level III interchange // tax rate applied to item // valid range is 0.01 to 0.99 (e.g. 1% to 99%) //ITM.TAXRAT = ''; // required for MasterCard, not listed for other card types // type of tax being applied //ITM.TAXTYPAPL = ''; // used to determine order items will appear in request // to CyberSource ITM.SEQ# = 1; // optional for Visa/MasterCard, not listed for other card types //ITM.DSCAMT = ''; // optional for MasterCard, not listed for other card types // Y or N indicates if the item is discounted - if you don't set this // but set a value in ITM.DSCAMT, CyberSource changes this to Y //ITM.DSCIND = ''; // Y=yes or N=no // required for MasterCard, not listed for other card types // Y or N indicates if tax amount is included in line item total //ITM.GRSNETIND = ''; //Y=yes or N=no // listed as optional for all card types // "Field to support an invoice number for a transaction. You // must specify the number of line items that will include an invoice // number. By default, the first line item will include an invoice // number field. The invoice number field can be included for // up to 10 line items //ITM.INVNBR = ''; // required for all card types // do not use all zeroes or spaces // total amount for item, typically price X quantity ITM.TOTAMT = '648.96'; // required for all card types for level 3 interchange // do not use all zeroes or spaces // unit of measure or unit of measure code for item //ITM.UOM = ''; write CTIWSITM.CTIWSITMR ITM; clear ITM; ITM.PID = UniqueId; ITM.UID = CTI_NextUniqueId(); ITM.CRTDT = %Timestamp(); ITM.PRDNAM = 'File Folders'; ITM.PRDCD = 'default'; ITM.QTY = 50; ITM.UNTPRC = '4.99'; ITM.TAXAMT = '20.58'; ITM.SEQ# = 2; ITM.TOTAMT = '270.08'; write CTIWSITM.CTIWSITMR ITM; if not CTI_Run( UniqueId : ErrorDS : CardNumber : *Omit : MerchantId ); // If CTI_Run() returns *Off then an error occured. // You should check ErrorDS subfields for info: // ErrorDS.Subproc = Name of CTI subprocedure that threw error // ErrorDS.MessageId = Message ID of the error message // ErrorDS.Message = Error message description // ErrorDS.LogFile = Path to a log file created in the IFS that can // be used for troubleshooting. Log files are generated // automatically whenever an error occurs. You can also force log // files to generate by modifying the value of the LOGALL field in // CTICFGMCH for the provided Merchant ID. // ErrorDS.Source = // - CTI_SOURCE_INTERNAL is a general product error. // This could be due to issues with input data, or the // inability to access physical files, etc. // // - CTI_SOURCE_TRANSMIT is a product error that specifically // occurred during HTTPS communication with the CyberSource // webservice. This could be due to issues with your network // configuration, proxy setup, internet connection, etc. // // - CTI_SOURCE_REMOTE is an error message provided by CyberSource. WriteToJobLog( 'Error Message Id: ' + ErrorDS.MessageId + NewLine ); WriteToJobLog( 'Error Message: ' + ErrorDS.Message + NewLine ); WriteToJobLog( 'Error Source: ' + ErrorDS.Source + NewLine ); // All error information is also written to the file CTIERR. else; // If CTI_Run() returned *On the request was successful. You can // access the results in the CTIWSRSP file using the same UniqueID // that was used to create the request record in CTIWSRSP. chain UniqueId CTIWSRSP.CTIWSRSPR RSP; if %Found(CTIWSRSP); // For this sample code we're writing the response data to the job // log, but generally you would extract the data and pass it into // your own data tables. The CTIWSHDR, CTIWSITM, and CTIWSRSP files // should not be used for long-term data storage and should instead // be considered short-term transactional files. // Authorization Response fields WriteToJobLog( 'CCAMT: ' + RSP.CCAMT + NewLine ); WriteToJobLog( 'CCATHCD: ' + RSP.CCATHCD + NewLine ); WriteToJobLog( 'CCATHDT: ' + RSP.CCATHDT + NewLine ); WriteToJobLog( 'RSNCD: ' + %Char(RSP.RSNCD) + NewLine ); WriteToJobLog( 'CCRSNCD: ' + RSP.CCRSNCD + NewLine ); WriteToJobLog( 'REQID: ' + RSP.REQID + NewLine ); WriteToJobLog( 'REQTK: ' + RSP.REQTK + NewLine ); WriteToJobLog( 'CCAVSCD: ' + RSP.CCAVSCD + NewLine ); WriteToJobLog( 'CCAVSCDR: ' + RSP.CCAVSCDR + NewLine ); WriteToJobLog( 'CCPRCRSP: ' + RSP.CCPRCRSP + NewLine ); // Capture Response fields WriteToJobLog( 'MCHREFCD: ' + RSP.MCHREFCD + NewLine ); WriteToJobLog( 'CAPAMT: ' + RSP.CAPAMT + NewLine ); WriteToJobLog( 'RSNCD: ' + %Char(RSP.RSNCD) + NewLine ); WriteToJobLog( 'CAPRSNCD: ' + %Char(RSP.CAPRSNCD) + NewLine ); WriteToJobLog( 'REQID: ' + RSP.REQID + NewLine ); WriteToJobLog( 'REQTK: ' + RSP.REQTK + NewLine ); WriteToJobLog( 'CAPREQDT: ' + RSP.CAPREQDT + NewLine ); WriteToJobLog( 'CAPRECID: ' + RSP.CAPRECID + NewLine ); endif; endif; *INLR = *On; return;