Sale
This transaction obtains real-time authorization for an EMV, magnetic stripe, contactless or manual card entry transaction and enters the transaction in the Unsettled batch. This transaction also logs purchases by cash.
Commerce SDK handles all the necessary prompting and flow regardless if the card is EMV, magnetic stripe, contactless or manual entry.
important
For a credit card transaction, a connected valid terminal is mandatory.
These are the processing options that you can integrate with a card Sale transaction:
- Address Verification Service
- Force Sale
- Gratuity
- Manual Card Entry
- Merchant Transaction Reference
- Partial Approval
- Token Request
- Pay with Token
- Invoice Number
Code Samples
CWS
Request
Property | Description |
---|---|
method string | required | startPaymentTransaction |
requestId string | required | Transaction Request ID |
targetType string | required | paymentGatewayConverge |
parameters JSONObject | required | All relevant parameters for Sale transactions. |
paymentGatewayId string | required | Payment Gateway ID Unique identifier of the payment gateway as returned in the openPaymentGateway transaction response. |
transactionType string | required | Transaction Type Valid value: SALE |
baseTransactionAmount JSONObject | required | Transaction Amount “baseTransactionAmount” : { “currencyCode” : “USD”, “value” : 1900 }, Note: Value for monetary amounts is always in minor units. |
tenderType string | required | Tender Type Valid value: CARD or CASH |
taxAmounts array | optional | Tax Default: 0 |
isTaxInclusive boolean | optional | Is Tax Included in Transaction Amount Valid values: - true - false (Default) |
discountAmounts array | optional | Discount Amount Deducted from baseTransactionAmount .key: “currencyCode” (“USD”) key: “value” (“2000” - in minor units) |
Response
Property | Description |
---|---|
requestId string | Transaction request ID specified in request. |
statusDetails string | Status of the request. |
data JSONObject | Object holding various responses. |
paymentGatewayCommand JSONObject | Payment Gateway Command |
completed boolean | Transaction Status |
eventQueue array | Event Queue List of events that occurred and its corresponding timestamps. |
chanId boolean | Transaction ID Identifier used to query the status of the transaction until completion. |
Example
Request
Kick off a back end transaction.
{
"method" : "startPaymentTransaction",
"requestId" : "32878540",
"targetType" : "paymentGatewayConverge",
"version" : "1.0",
"parameters" : {
"paymentGatewayId" : "11b0032b-eb0d-4d9a-8664-eb430684cb92",
"transactionType" : "SALE",
"baseTransactionAmount" : {
"value" : 2000,
"currencyCode" : "USD"
},
"tenderType" : "CARD",
"cardType" : null,
"isTaxInclusive" : false,
"taxAmounts" : [{
"value" : 0,
"currencyCode" : "USD"
}],
"discountAmounts" : null
}
}
Later to query the status of the transaction.
{
"method" : "getPaymentTransactionStatus",
"requestId" : "32878541",
"targetType" : "paymentGatewayConverge",
"version" : "1.0",
"parameters" : {
"paymentGatewayId" : "11b0032b-eb0d-4d9a-8664-eb430684cb92",
"chanId" : "239c9b47-c6c3-462b-8701-b83586bdf3e6"
}
}
Response
Incomplete
{
"requestId" : "32878540",
"statusDetails" : "REQUEST_ACCEPTED",
"data" : {
"paymentGatewayCommand" : {
"completed" : false,
"eventQueue" : [ {
"timeStamp" : "1457115273607",
"statusDetails" : "STARTING"
} ],
"chanId" : "239c9b47-c6c3-462b-8701-b83586bdf3e6"
}
}
EMV Successful
{
"requestId" : "1947227770",
"statusDetails" : "REQUEST_ACCEPTED",
"data" : {
"paymentGatewayCommand" : {
"completed" : true,
"eventQueue" : [ ],
"chanId" : "7c332149-ba08-497d-9c7f-ab57792dac1f",
"paymentTransactionData" : {
"result" : "APPROVED",
"authCode" : "******",
"iccAid" : "A0000000031010",
"iccAppName" : "Visa Credit",
"iccMode" : "ICC_MODE",
"iccTvr" : "80C0008000",
"iccTsi" : "6800",
"resultMessage" : "APPROVAL",
"iccCvmr" : "SIGNATURE",
"date" : "Fri Mar 04 13:21:39 MST 2016",
"cardEntryType" : "EMV_CONTACT",
"cardScheme" : "VISA",
"amount" : {
"currencyCode" : "USD",
"value" : 8700
},
"id" : "040316A15-F48AB876-9635-4933-B773-136888A3D972",
"transactionType" : "SALE",
"approved" : "yes",
"errors" : [ ],
"tax" : {
"currencyCode" : "USD",
"value" : 200
},
"maskedPan" : "******",
"gratuityAmount" : {
"currencyCode" : "USD",
"value" : 300
},
"signatureBitmap" : {
"data" : "` +J !_ P____ X _'___ _& _' ( _' _/ _' ( _/ _/ ( _7 _/ ( _7 _/ _7 _7 ( _/ _/ _/ _/ _' ( _& _%___ _'_______________________W____ X__W_ P____ Y_ P_ X !_ X \" ! ) ! ) ) ) ) ) 1 ) 1 * ) ( 1 ) 1 ) ) ( ) ) ( ) !p`#+Q ! 0 ! 0 0 ) 8 8 0 8 ) 0 _/ 0 0 _' ( _& (___ _& _'______ _&___ _'___ _&___ _'___ _'___ _& _'___ _/___ _' _/ _& _'p`'&__ X _&p`+)?_ P____ X___________W_ X________^_________ _'___ _'___ _/ _' _/ ( _/ 0 8 ( ( 1 ( ) 0 ) ) ) ) ) ! ) ! !_ Y ! !_ Y !_ Y_ Y_ Y_ Y_ X_ Y_ Xp`-*( _'_ X_______ X _'_ X _'_ X _'_ X _'___ _'______ _'__^ _' _' _' _/ _' _/ _/ 0 _/ 0 ( 0 ( 0 1 0 1 ( 1 ) 1 ) ) ) ! ) !_ Z !_ Y_ Y_ Q_ Z_ Q_ P_ Q_ Q_ Q_ H_ Q_ P_ Q_ P_ P__W_ X_ P___p",
"format" : "SIG_BIN_2"
},
"tenderType" : "CARD",
"balanceDue" : {
"currencyCode" : "UNKNOWN",
"value" : 0
}
}
}
}
}
Card Swipe Successful
{
"requestId" : "32878570",
"statusDetails" : "REQUEST_ACCEPTED",
"data" : {
"paymentGatewayCommand" : {
"completed" : true,
"eventQueue" : [ ],
"chanId" : "239c9b47-c6c3-462b-8701-b83586bdf3e6",
"paymentTransactionData" : {
"result" : "APPROVED",
"authCode" : "******",
"date" : "Fri Mar 04 13:14:54 MST 2016",
"cardEntryType" : "SWIPE",
"resultMessage" : "APPROVED",
"cardScheme" : "VISA",
"amount" : {
"currencyCode" : "USD",
"value" : 2500
},
"id" : "040316A15-6C692699-7640-454A-9FAE-7B2FBFADCB53",
"transactionType" : "SALE",
"approved" : "yes",
"errors" : [ ],
"tax" : {
"currencyCode" : "USD",
"value" : 200
},
"maskedPan" : "******",
"gratuityAmount" : {
"currencyCode" : "USD",
"value" : 300
},
"signatureBitmap" : {
"data" : "` *G_ P_ X !_ X ) ( ) ( ) 0 0 0 8 0 _/ ( _' ( _' ( _& _& _&___ _&_____^_____^ _'__V _&__V _'__^__W _'_____^ _'____ X _& _' ( _' 0 0 0 8 8 ) 8 ( 1 0 0 ) 0 0 0p`'*)_ X _'_ P _'_ X _'____ X _&_ X _& _' ( _' _/ _' ( _/ ( _/ _' 0 _/ 0 _' ( _/ ( _' ( _' ( _&___ _'___ _'_ X___ _'____ P _'__W_ X____ H_ X___p`&*0 \" ( ! ( ! ( ) ) ( ) ) ( ) 0 ) ( 1 0 ) 8 ) 8 (p`)&Y p`-)C_ X _'_ X____ X _'_ X _'______ _'___ _&___ _& _' _/ _' _/ ( _' ( _/ 8 8 0 ) ( 1 ) ) ! ( ) ) # ) \" \"_ Y !_ Y !_ Y_ Y_ Y_ Xp`0)J _'_ X _'_ X _&_ X _'___ _'_ X _&___ _& _& _& _/ ( _' ( _/ 0 8 ( 0 ) 0 ) ( 2 ( * ( * ) ! * ! ! \" !_ Y !_ Z_ Y_ Y_ X_ Q_ Y_ P_ Y_ P_ X_ Q_ P____ X_ Pp",
"format" : "SIG_BIN_2"
},
"tenderType" : "CARD",
"balanceDue" : {
"currencyCode" : "UNKNOWN",
"value" : 0
}
}
}
}
}
Failed
{
"requestId" : "670817917",
"statusDetails" : "REQUEST_ACCEPTED",
"data" : {
"paymentGatewayCommand" : {
"completed" : true,
"eventQueue" : [ {
"timeStamp" : "1447437024243",
"statusDetails" : "CARD_READER_TRANSACTION_COMPLETED"
} ],
"chanId" : "481c043e-78ad-410b-bb48-44ee2526be2a",
"paymentTransactionData" : {
"id" : "131115CAD-A66E04AD-E559-4A7D-AF29-17E2BA8D4A77",
"result" : "DECLINED",
"authCode" : "******",
"transactionType" : "SALE",
"approved" : "no",
"errors" : [ ],
"maskedPan" : "******",
"tenderType" : "CREDIT_CARD",
"date" : "Fri Nov 13 12:50:19 MST 2015",
"cardScheme" : "VISA"
}
}
}
}
Java
To submit a Sale transaction, complete the following steps:
Initialize Commerce SDK and receive an
ECLAccountInterface
instance named account.Create a money object by specifying a currency code and an amount.
ECLMoney amount = new ECLMoney(ECLCurrencyCode.USD, 300L);
Create a transaction reference.
ECLCurrencyTransactionInterface transaction = account.getTransactionProcessor().createSaleTransactionWithSubtotal(amount);
Create a tender instance.
Card Tender
ECLCardTenderInterface tender = account.getTransactionProcessor().createCardTender();
Cash Tender
ECLCashTenderInterface tender = account.getTransactionProcessor().createCashTender();
Create a transaction processing listener. The transaction processing listener enables your application to receive callbacks during transaction processing.
// Create an Instance of ECLTransactionProcessingListener (handle all callbacks and any requests for information during transaction processing) ECLTransactionProcessingListener transactionListener = new ECLTransactionProcessingListener() { /** * Transaction Completed ... How did it turn out? */ @Override public void transactionDidComplete(ECLTransactionInterface transaction, ECLTenderInterface tender, final ECLTransactionOutcome outcome) { if (outcome == null) { // Warning - No outcome was present logger.warning("transaction completed... with null outcome"); } else if (outcome.isApproved()) { // Transaction was APPROVED!!! Use the "outcome" instance for transaction details (approval code, etc.) } else { // Transaction was DECLINED!!! Use the "outcome" instance for transaction details (approval code, etc.) } // Can check error field to see if an error occurred during the processing. // Can check signatureError field to see why signature failed to be sent if (outcome.isSignatureSent()) { // Signature collected and sent for transaction. } // If the transaction happened to utilize an EMV chip card, check for any errors. if (outcome instanceof ECLEmvCardTransactionOutcome) { ECLEmvCardTransactionOutcome emvOutcome = (ECLEmvCardTransactionOutcome)outcome; // reversal error is if the transaction was approved by Converge server and card declined it but Commerce were unable to tell Converge server to reverse. showErrors("reversal error", Arrays.asList(emvOutcome.getReversalError())); // update error is if after transaction completed the card told us to update the EMV properties associated with the transaction but commerce failed to do that. showErrors("update error", Arrays.asList(emvOutcome.getUpdateTransactionError())); } } @Override public void transactionDidCancel(ECLTransactionInterface transaction, ECLTenderInterface tender) { // Transaction was cancelled. Time to move on... } @Override public void transactionDidFail(ECLTransactionInterface transaction, ECLTenderInterface tender, List<ECCError> errors) { // Uh oh, transaction failed. Display the errors (list). } @Override public void shouldProvideInformation(final ECLTransactionInterface transaction, final ECLTenderInterface tender, final ECLTransactionRequirementsInterface transactionRequires, final ECLTenderRequirementsInterface tenderRequires) { // Hold on, we need more information to process the transaction! // During transaction processing, this callback may be executed one or more times for the purpose // of collecting more information to continue processing the transaction. boolean continueTransaction = false; if (tenderRequires.isDigitalSignatureRequired()) { // Transaction Requires a [Digital] Signature! // The example below simply provides a basic image block to satisfy the signature image requirement. // If using a smartphone, for example, capture the signature on-screen and then pass the signature image to Commerce SDK. // Should the signature be cancelled at this point (i.e. "cardTender.cancelSignature();"), Commerce SDK will include a blank signature line on the printed receipt. Thread thread = new Thread() { @Override public void run() { GetSignatureDialog getSignatureDialog = new GetSignatureDialog(); getSignatureDialog.setLocationRelativeTo(parentFrame); getSignatureDialog.setVisible(true); ECLCardTenderInterface cardTender = (ECLCardTenderInterface) tender; if (getSignatureDialog.isClickedOK()) /* Did the user click OK? */ { ECLDimension minSize = tenderRequires.getMinimumDigitalSignatureSize(); deckard.graphics.desktop.DesktopBitmap sig = new deckard.graphics.desktop.DesktopBitmap(); sig.initialize(minSize.getWidth(), minSize.getHeight(), Bitmap.Config.BLACK_AND_WHITE); sig.fillWithColor(0, 0, minSize.getWidth(), minSize.getHeight(), Color.BLACK); cardTender.setDigitalSignature(new ECLSignatureData(sig)); } else { cardTender.cancelSignature(); } account.getTransactionProcessor().continueProcessingTransaction(transaction, tender, transactionListener); } }; thread.start(); return; } if (tenderRequires.getRequiresVoiceReferral() != ECLVoiceReferralRequirement.NOT_REQUIRED) { // Voice Referral Required! // Some transactions may require calling the issuer to obtain an approval code. // Should this be required, pass the approval code to Commerce SDK once the code has been provided. ((ECLCardTenderInterface) tender).setVoiceReferralHandledAndApproved("321"); continueTransaction = true; } if (tenderRequires.getRequiresSignatureVerification() != ECLSignatureVerificationRequirement.NOT_REQUIRED) { // Signature Verification Required! // In some cases, processing may ask to verify the cardholder's signature. Once verified, the transaction processing may continue. ((ECLCardTenderInterface) tender).setSignatureVerificationHandledAndVerified(); continueTransaction = true; } if (tenderRequires.requiresSpecifyingCardPresence()) { // Is the Card Physically Present at the Time of Processing? // When manually entering a card number, it may be necessary to indicate if the card is physically present and in-hand. // If the card is not present, the state should be set to "NO". Thread thread = new Thread() { @Override public void run() { CardPresentDialog dialog = new CardPresentDialog(); dialog.setLocationRelativeTo(parentFrame); dialog.setVisible(true); if (dialog.isClickedOK()) { if (dialog.isCardPresent()) { ((ECLCardTenderInterface) tender).setCardPresent(ECLTriState.YES); } else { ((ECLCardTenderInterface) tender).setCardPresent(ECLTriState.NO); } account.getTransactionProcessor().continueProcessingTransaction(transaction, tender, transactionListener); } else { account.getTransactionProcessor().cancelTransaction(transaction, tender, transactionListener); } } }; thread.start(); return; } if (transactionRequires.isGratuityRequired() && transaction instanceof ECLCurrencyTransactionInterface) { // Transaction Supports Gratuity... Was a value already determined/provided? If so, set the amount here. ((ECLCurrencyTransactionInterface)transaction).setGratuity(null); logger.info(" Gratuity"); continueTransaction = true; } if (continueTransaction) { // Has the required information been provided? If so, continue transaction processing. logger.warning("shouldProvideInformation continue"); account.getTransactionProcessor().continueProcessingTransaction(transaction, tender, transactionListener); } else { logger.warning("shouldProvideInformation unhandled - canceling transaction"); account.getTransactionProcessor().cancelTransaction(transaction, tender, transactionListener); } } @Override public void shouldSetCardReaderToUse(ECLTransactionInterface transaction, ECLTenderInterface tender, List<String> cardReadersReadyForUse) { // Lucky day, more than one card reader is available! // Should this scenario arise, provide a mechanism to select the appropriate card reader. logger.warning("unhandled shouldSetCardReaderToUse(List) so canceling transaction"); } public void transactionProgress(final ECLTransactionProgress progress, final ECLTransactionInterface transaction, final ECLTenderInterface tender) { // Always good to know what is happening while the transaction is processing! // Use this callback to provide status information (i.e. "progress" messages) logger.info(String.format("ECLTransactionProcessingListener transactionProgress %s", progress.name())); } };
Start the transaction.
account.getTransactionProcessor().processTransaction(transaction, tender, transactionListener);
Objective-C
To submit a Sale transaction, complete the following steps:
Initialize Commerce SDK and receive an
ECLAccountInterface
instance named account.Create a money object by specifying a currency code and an amount.
ECLMoney *amount = [[ECLMoney alloc] initWithMinorUnits:300 withCurrencyCode:ECLCurrencyCode_USD];
Create a transaction protocol.
id<ECLCurrencyTransactionProtocol> transaction = [account.transactionProcessor createSaleTransactionWithSubtotal:amount];
Create a tender instance.
Card Tender
id<ECLCardTenderProtocol> tender = [account.transactionProcessor createCardTender];
Cash Tender
id<ECLCashTenderProtocol> tender = [account.transactionProcessor createCashTender]; // Need to set the amount of cash handed to us from the customer // Here we will set it to the same amount as it costs tender.amountTendered = amount;
Create a transaction processing delegate. The transaction processing delegate enables your application to receive callbacks during transaction processing.
// in your header file #import <Commerce-Converge/ECLTransactionProcessingDelegate.h> @interface TransactionProcessingDelegate : NSObject<ECLTransactionProcessingDelegate> // In your .m file #import "TransactionProcessingDelegate.h" #import <Commerce-Converge/ECLAccountProtocol.h> #import <Commerce-Converge/ECLTransactionProcessorProtocol.h> #import <Commerce-Converge/ECLCurrencyTransactionProtocol.h> #import <Commerce-Converge/ECLTransactionRequirementsProtocol.h> #import <Commerce-Converge/ECLCardTenderProtocol.h> #import <Commerce-Converge/ECLEmvCardTransactionOutcome.h> #import <CommerceDataTypes/CommerceDataTypes.h> #import <Commerce-Converge/ECLTenderRequirementsProtocol.h> #import <Commerce-Converge/ECLTransactionProgress.h> #import <Commerce-Converge/ECLDebugDescriptions.h> @implementation TransactionProcessingDelegate + (void)transactionDidComplete:(id<ECLTransactionProtocol>)transaction using:(id<ECLTenderProtocol>)tender outcome:(ECLTransactionOutcome *)outcome { if (outcome == nil) { NSLog(@"nil outcome"); return; } if (outcome.error != nil) { NSLog(@"transactionDidComplete with error: %@", outcome.error.debugDescription); } // can also check signatureError to see if we failed to send signature if (outcome.isApproved == YES) { // Transaction was APPROVED!!! Use the "outcome" instance for transaction details (approval code, etc.) } else { // Transaction was DECLINED!!! Use the "outcome" instance for transaction details (approval code, etc.) } if ([outcome isKindOfClass:[ECLCardTransactionOutcome class]]) { // Outcome is for a Card Transaction so cast to ECLCardTransactionOutcome to get more info if ([outcome isKindOfClass:[ECLEmvCardTransactionOutcome class]]) { // Outcome is for a EMV Card Transaction so cast to ECLEmvCardTransactionOutcome to get more info // including checking if we failed to reverse a transaction from reverseError property // or we failed to update a transaction on the server from updateError property } } } + (void)transactionDidCancel:(id<ECLTransactionProtocol>)transactionParam using:(id<ECLTenderProtocol>)tenderParam { // Transaction was canceled } + (void)transactionDidFail:(id<ECLTransactionProtocol>)transactionParam using:(id<ECLTenderProtocol>)tenderParam errors:(NSArray *)arrayOfNSErrors { // Transaction failed. Check the array of NSErrors to see why. // Use nsError.debugDescription to log more information } + (void)shouldProvideInformation:(id<ECLTransactionProtocol>)transactionParam tender:(id<ECLTenderProtocol>)tenderParam transactionRequires:(id<ECLTransactionRequirementsProtocol>)transactionRequires tenderRequires:(id<ECLTenderRequirementsProtocol>)tenderRequires { // We need more information to process the transaction! // During transaction processing, this callback may be executed one or more times for the purpose // of collecting more information to continue processing the transaction. // SEE SAMPLE APP FOR OTHER REQUIREMENTS YOU SHOULD PROVIDE WHEN THIS METHOD IS CALLED. Listed here is only sample of those. BOOL continueTransaction = NO; if (transactionRequires.requiresGratuity) { // Transaction requires gratuity to be set but if we don't want to set any we can set it to nil. // Lets make sure it is a ECLCurrencyTransactionProtocol if ([transactionParam conformsToProtocol:@protocol(ECLCurrencyTransactionProtocol)]) { id<ECLCurrencyTransactionProtocol> currencyTransaction = (id<ECLCurrencyTransactionProtocol>)transactionParam; [currencyTransaction setGratuity:nil]; continueTransaction = YES; } } if (tenderRequires.requiresVoiceReferral != ECLVoiceReferral_NotRequired) { // Voice Referral Required! // Some transactions may require calling the issuer to obtain an approval code. // Should this be required, pass the approval code to Commerce SDK once the code has been provided. // Lets make sure it is a ECLCardTenderProtocol if ([tenderParam conformsToProtocol:@protocol(ECLCardTenderProtocol)]) { id<ECLCardTenderProtocol> cardTenderProtocol = (id<ECLCardTenderProtocol>)tenderParam; [cardTenderProtocol setVoiceReferralHandledAndApproved:@"321"]; // we should show UI to get Authorization Code // and call continueTransaction after we get it but here we just set it continueTransaction = YES; } } if (tenderRequires.requiresSignatureVerification != ECLSignatureVerification_NotRequired) { // Signature Verification Required! // In some cases, processing may ask to verify the cardholder's signature. Once verified, the transaction processing may continue. // Lets make sure it is a ECLCardTenderProtocol if ([tenderParam conformsToProtocol:@protocol(ECLCardTenderProtocol)]) { id<ECLCardTenderProtocol> cardTenderProtocol = (id<ECLCardTenderProtocol>)tenderParam; [cardTenderProtocol setSignatureVerificationHandledAndVerified]; // we should show UI to ask for verification // and call continueTransaction after we get it but here we just set it continueTransaction = YES; } } if (tenderRequires.requiresDigitalSignature){ // We should launch signature capture UI and setDigitalSignature on ECLCardTenderProtocol and call continueTransaction // See sample app how to capture signature. Search for the line below // [myViewController performSegueWithIdentifier:@"signatureScreenSegue" sender:self]; // return; // but for now lets cancel the signature and that will print a line on the receipt for customer to sign // Lets make sure it is a ECLCardTenderProtocol if ([tenderParam conformsToProtocol:@protocol(ECLCardTenderProtocol)]) { id<ECLCardTenderProtocol> cardTenderProtocol = (id<ECLCardTenderProtocol>)tenderParam; [cardTenderProtocol cancelSignature]; continueTransaction = YES; } } if (continueTransaction) { // NOTE: You should always do a dispatch_async when calling from a delegate method back into Commerce to process a transaction or before showing UI dispatch_async(dispatch_get_main_queue(), ^() { // continue the transaction because we updated required information [yourInstanceOfECLAccountProtocol.transactionProcessor continueProcessingTransaction:transactionParam using:tenderParam delegate:self]; }); } else { // we failed to provide the information. Should cancel transaction. Check log for what was required } } + (void)shouldSetCardReaderToUse:(id<ECLTransactionProtocol>)transactionParam tender:(id<ECLTenderProtocol>)tenderParam cardReaders:(NSArray *)cardReadersReadyForUse { // Commerce detected more than one card reader so you need to let the user choose which one from the list of NSStrings in cardReadersReadyForUse // Should this scenario arise, provide a mechanism to select the appropriate card reader. // NOTE: You should always do a dispatch_async when calling from a delegate method back into Commerce to process a transaction or before showing UI dispatch_async(dispatch_get_main_queue(), ^() { // Show your UI here // Then call yourInstanceOfECLAccountProtocol.cardReaders setDeviceToUse to set the card reader chosen // Then call yourInstanceOfECLAccountProtocol.transactionProcessor continueProcessingTransaction }); return; } + (void)transactionProgress:(ECLTransactionProgress)progress transaction:(id<ECLTransactionProtocol>)transactionParam using:(id<ECLTenderProtocol>)tenderParam { // Always good to know what is happening while the transaction is processing! // Use this callback to provide status information (i.e. "progress" messages) NSLog(@"transactionProgress %@", [ECLDebugDescriptions descriptionOfTransactionProgress:progress]); }
Start the transaction.
TransactionProcessingDelegate *delegate = [[TransactionProcessingDelegate alloc] init]; [account.transactionProcessor processTransaction:transaction using:tender delegate:delegate];
C#
A sale transaction with a card tender for $3.25.
Request
PaymentArgs bea = new PaymentArgs();
Money m = new Money(Money.CurrencyCodefromString("USD"), 325);
bea.baseTransactionAmount = m;
bea.tenderType = TenderType.CARD;
/* If you were using a CASH tender you will also need to set 'bea.tenderedAmount' to the amount of cash you took from the customer */
bea.transactionType = TransactionType.SALE;
bea.paymentGatewayId = m_PaymentGatewayId;
m_CWS.StartPaymentTransaction(bea, MyNotifyCWSEvent, MyPaymentComplete);
Response
public void MyPaymentComplete(PaymentTransactionResults ber)
{
PaymentTransactionData betd = ber.PaymentTransactionData;
if (null != betd)
{
if (null != betd.errors)
{
for (int i = 0; i < betd.errors.Length; i++)
{
Log(String.Format("Error[{0}] = {1}", i, betd.errors[i]));
}
}
if ((null != betd.approved) && (betd.approved.Equals("yes")))
{
/* transaction was approved */
}
}
String[] req = ber.getRequiredInformation();
if (null != req)
{
Log("---- Information Required ----");
for (int i = 0; i < req.Length; i++)
{
Log(String.Format("Required[{0}] = {1}", i, req[i]));
}
}
}