Sorry to get your hopes up but I am reliably informed that you cannot do this. And the reason? “PCI Compliance”.
Let me take a few steps back and explain. When you use the EFT module (which is standard in the UK version) to automatically populate a batch with gifts there is a field called Rejection Code. I do not know the details of exactly how Blackbaud use this together with IATS and ICVerify but it is there. What is more you are able to populate it with your own rejection codes. When I was working with one organisation they did just that. They would send of their transmission file to BACS and enter the reason for a payment rejection into the rejection code field. When they then committed the batch any rows with a value in the rejection code field would cause and batch row exception and would give the rejection code as the reason. Those rows would then be added to a new exception batch for processing or discarding as seen fit. Sounds like a good system to me.
I am currently working on some banking procedures for a client from a country outside of Blackbaud’s core countries (US, Canada, UK, Australia, New Zealand, etc) where there is no banking process built into RE. They have a similar process. Create a transmission file for a batch of gifts, send it off to the clearing house and wait for any rejections. I had planned to use the API to populate the rejection code field in the batch so that those rows would cause an exception.
The first problem was that the rejection code is not part of a gift object. Instead I simply looped through the fields in the batch looking for the one with the name “Rejection Code”. Once I had found its position I could simply write to the tempRecord as below:
For Each batchField In batchFields If batchField.Fields(EBatchFieldFields.BatchField_fld_FieldName) = "Rejection code" Then rejectCodeField = batchField.Fields(EBatchFieldFields.BatchField_fld_Sequence) Exit For End If Next batchField tempRecord.Fields(rejectCodeField) = rejectCode
This worked fine. The value was in the tempRecord (I queried it in the immediate window and the value was there). I saved the tempRecords collection, saved the batch and went to look in the batch to see if it was there. There was no sign of the value. Just empty.
When I asked Blackbaud support for an example of how to do this they were not able to do so either. I said that it must be possible as the IATS and ICVerify code writes to these fields. Could you not simply let me see the code that they use to write to this field. So I perhaps should not have asked to see the code but rather be told how they do it. However the response I received was that:
“We do not provide code for IATS, BBPS, or ICVerify as this would violate PCI compliance.”
After some explanation I was told:
“It is not populating a rejection code field that would be a violation of PCI compliance. However, revealing source code from IATS or ICVerify would be a violation of compliance.”
I really do not understand how giving me the technique that was used is in breach of PCI compliance. What seems more likely is that the solution uses “the other API” i.e. the dlls that RE uses itself and not the one that is exposed to users of the RE:API module. There are several circumstances when you have to use the RE dlls when working with batch (as has been highlighted earlier in this blog). What is interesting is that if you search the object browser for “reject” you get the following fields:
Public Const GIFTREJECTIONCODE As Blackbaud.PIA.RE7.BatchData.EBATCH_GiftSpecialFields = 202
Public Const BatchGift_Fld_RejectionCode As Blackbaud.PIA.RE7.BatchData.EBatchGiftFields = 64
The question is how are they used with the other batch objects to get this solution to work. If anyone know please do leave a comment!
I was able to populate the Rejection code field in a batch using this code (creates a copy of an existing batch).
Private Sub CreateBackupBatch(ByVal sSrcBatchNbr As String)
Dim oSrcBatch As CBatchAPI = New CBatchAPI
Dim oBkpBatch As CBatchAPI = New CBatchAPI
Dim oBkpTempRecords As CTempRecords
‘ Create a new, empty batch based on the design of an existing batch
CreateBatchFromTemplate(sSrcBatchNbr, sSrcBatchNbr & ” BKP”)
oSrcBatch.Init(coSC)
Try
oSrcBatch.LoadByNumber(sSrcBatchNbr)
Catch ex As Exception
Throw ex
End Try
oBkpBatch.Init(coSC)
Try
oBkpBatch.LoadByNumber(sSrcBatchNbr & ” BKP”)
Catch ex As Exception
Throw ex
End Try
oBkpTempRecords = oBkpBatch.TempRecords
oBkpBatch.Fields(EBatchAPIFields.BATCHAPI_fld_BATCH_NUMER) &= ” ” & Now.ToString
oBkpBatch.Save()
Dim oSrcBatchFields As CBatchFields = oSrcBatch.BatchFields
‘ Copy all batch rows except the template row from source to target
For Each oSrcTempRec As CTempRecord In oSrcBatch.TempRecords
If oSrcTempRec.Fields(oSrcBatchFields.Count + 2) “0” Then
‘ BD (below) is an import alias for Blackbaud.PIA.RE7.BatchData,
‘ all other Batch API classes are referenced from Blackbaud.PIA.RE7.BBREAPI
Dim oBkpTempRec As BD.CTempRecord = oBkpTempRecords.Add()
oBkpTempRec.DataObject = oSrcTempRec.DataObject
For Each oSrcBatchField As CBatchField In oSrcBatchFields
Dim i As Integer = oSrcBatchField.Fields(EBatchFieldFields.BatchField_fld_Sequence)
If oBkpTempRec.Fields(i) oSrcTempRec.Fields(i) Then
oBkpTempRec.Fields(i) = oSrcTempRec.Fields(i)
End If
Next
End If
oBkpTempRecords.Save()
Next
oBkpBatch.Save()
oBkpTempRecords = Nothing
oSrcBatch.CloseDown()
FinalReleaseComObject(oSrcBatch)
oBkpBatch.CloseDown()
FinalReleaseComObject(oBkpBatch)
End Sub
I’ve had similar weird problems, maybe you have a suggestion…
When I try to populate GIFT_fld_Check_Number it doesn’t seem to actually populate (no errors, it just never shows up in RE despite definitely being populated in my debug checks). When I try to populate GIFT_fld_Description, it throws what to me appears to be an entirely unrelated error about a column that I’m not attempting to access. BATCHAPI_fld_DESCRIPTION, on the other hand, works beautifully.
Have you tried using these fields at all? Any thoughts? I wish there were more documentation on this stuff.
Thanks much
-Heather
Cate,
Thanks for your suggestions. I will definitely give it a go. One workaround would be to copy an existing batch and change the values. The problem is that no two batches are alike. The number of gifts in a batch vary so while I could copy a previous batch, or even set up a batch template in the GUI in order to copy that batch over, I would have to ensure that there were a large number of gifts present to cover the number that I may require in a later batch. I would have to loop through it and then change the values from the template batch to the new batch. Of course this could work but it is really long winded workaround which really should not be necessary.
Heather, I have, unfortunately, not tried to write the check number to a batch. It does sound like a similar case. Are you able to populate it through the GUI?
David
Heather,
Did you manage to solve the check number issue? I too now need to populate that field and it does not seem like it is doing so.
UPDATE: I realised that you need to have the payment type set to cheque (or check depending where you are in the world!). It will then work.
David