When completing a released shipment on a multishipment order , how do I know in the payment gateway, which shipment that was completed

CompleteShipment in DefaultShipmentProcessor uses this method that use the extension method ProcessPayments
private void CompleteShipment(IOrderGroup order, IShipment shipment)
this.CapturePayment(order, shipment);
if (order.Forms.Sum<IOrderForm>((Func<IOrderForm, Decimal>) (form => form.Payments.Sum<IPayment>((Func<IPayment, Decimal>) (p => p.Amount)))) < order.GetTotal(this._orderGroupCalculator).Amount)
throw new Exception("Payment total is less than order total.");
IEnumerable<PaymentProcessingResult> source = order.ProcessPayments(this._paymentProcessor, this._orderGroupCalculator).Where<PaymentProcessingResult>((Func<PaymentProcessingResult, bool>) (r => !r.IsSuccessful));
if (source.Any<PaymentProcessingResult>())
string message = string.Join(Environment.NewLine, source.Select<PaymentProcessingResult, string>((Func<PaymentProcessingResult, string>) (e => e.Message)));
throw new PaymentException(PaymentException.ErrorType.ProviderError, string.Empty, message);
The extension method ProcessPayments runs paymentProcessor.ProcessPayment(ordergroup, payment, (IShipment) null)
public static IEnumerable<PaymentProcessingResult> ProcessPayments(
this IOrderGroup orderGroup,
IPaymentProcessor paymentProcessor,
IOrderGroupCalculator orderGroupCalculator)
if (orderGroup.GetTotal(orderGroupCalculator).Amount == Decimal.Zero || orderGroup is IPaymentPlan)
return Enumerable.Empty<PaymentProcessingResult>();
List<PaymentProcessingResult> processingResultList = new List<PaymentProcessingResult>();
foreach (IOrderForm form in (IEnumerable<IOrderForm>) orderGroup.Forms)
processingResultList.AddRange(form.Payments.Select<IPayment, PaymentProcessingResult>((Func<IPayment, PaymentProcessingResult>) (payment => paymentProcessor.ProcessPayment(orderGroup, payment, (IShipment) null))));
return (IEnumerable<PaymentProcessingResult>) processingResultList;
Since shipment will be null here, the switch statement will NEVER call ProcessPayment with shipment information if PaymentGateway implements ISplitPaymentPlugin?????
 public virtual PaymentProcessingResult ProcessPayment(
IOrderGroup orderGroup,
IPayment payment,
IShipment shipment)
Validator.ThrowIfNull(nameof (payment), (object) payment);
if (PaymentStatusManager.GetPaymentStatus(payment) != PaymentStatus.Pending)
return PaymentProcessingResult.CreateSuccessfulResult(string.Empty);
object paymentGatewayProvider = this.CreatePaymentGatewayProvider(payment);
string empty = string.Empty;
PaymentProcessingResult processingResult;
switch (paymentGatewayProvider)
case ISplitPaymentPlugin splitPaymentPlugin when shipment != null:
processingResult = splitPaymentPlugin.ProcessPayment(orderGroup, payment, shipment);
case IPaymentPlugin paymentPlugin:
processingResult = paymentPlugin.ProcessPayment(orderGroup, payment);
case ISplitPaymentGateway splitPaymentGateway when shipment != null && (payment is Payment payment1 && shipment is Shipment shipment1):
processingResult = splitPaymentGateway.ProcessPayment(payment1, shipment1, ref empty) ? PaymentProcessingResult.CreateSuccessfulResult(empty) : PaymentProcessingResult.CreateUnsuccessfulResult(empty);
processingResult = ((IPaymentGateway) paymentGatewayProvider).ProcessPayment(payment as Payment, ref empty) ? PaymentProcessingResult.CreateSuccessfulResult(empty) : PaymentProcessingResult.CreateUnsuccessfulResult(empty);
Apr 06, 2020 14:52

Yeah, as you see you cannot get the specific shipment inside your split payment plugin, unless you specifically call the ProcessPayments method yourself.

However, before calling your split payment plugin, the CompleteShipment method inserts a capture payment in the shipment's OrderForm parent with the total shipment amount.

So, unless you need to mark some custom Shipment properties upon payment completion, I guess your split payment plugin could be made in a way that it doesn't need to know the specific shipment. At least you don't need to calculate the shipment amount to pay.

Apr 26, 2020 6:43
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.