@commercetools/connect-payments-sdk
Advanced tools
Comparing version 0.0.7 to 0.1.0
# @commercetools/connect-payments-sdk | ||
## 0.1.0 | ||
### Minor Changes | ||
- f782132: Added validations for the different payment modification operations | ||
Improved logic for calculating the cart payment amount | ||
## 0.0.7 | ||
@@ -4,0 +11,0 @@ |
@@ -12,4 +12,6 @@ import { CartService, CartServiceOptions, GetCart, GetPaymentAmount } from '../types/cart.type'; | ||
getCart(opts: GetCart): Promise<Cart>; | ||
getPaymentAmount(opts: GetPaymentAmount): PaymentAmount; | ||
getPaymentAmount(opts: GetPaymentAmount): Promise<PaymentAmount>; | ||
addPayment(opts: AddPayment): Promise<Cart>; | ||
private calculateTotalPaidAmount; | ||
private calculatePaymentAmount; | ||
} |
@@ -5,2 +5,3 @@ "use strict"; | ||
const ct_api_error_1 = require("../errors/ct-api.error"); | ||
const __1 = require("../.."); | ||
/** | ||
@@ -17,5 +18,7 @@ * Default implementation of the CartService interface. | ||
} | ||
getPaymentAmount(opts) { | ||
async getPaymentAmount(opts) { | ||
const paidAmount = await this.calculateTotalPaidAmount(opts.cart); | ||
let cartAmount; | ||
if (opts.cart.taxedPrice) { | ||
return { | ||
cartAmount = { | ||
currencyCode: opts.cart.taxedPrice.totalGross.currencyCode, | ||
@@ -25,6 +28,23 @@ centAmount: opts.cart.taxedPrice.totalGross.centAmount, | ||
} | ||
return { | ||
currencyCode: opts.cart.totalPrice.currencyCode, | ||
centAmount: opts.cart.totalPrice.centAmount, | ||
}; | ||
else { | ||
cartAmount = { | ||
currencyCode: opts.cart.totalPrice.currencyCode, | ||
centAmount: opts.cart.totalPrice.centAmount, | ||
}; | ||
} | ||
if (paidAmount >= cartAmount.centAmount) { | ||
throw new __1.ErrorInvalidOperation('The cart has already been paid in full', { | ||
fields: { | ||
resource: opts.cart.id, | ||
paidAmount, | ||
cartAmount, | ||
}, | ||
}); | ||
} | ||
else { | ||
return { | ||
currencyCode: cartAmount.currencyCode, | ||
centAmount: cartAmount.centAmount - paidAmount, | ||
}; | ||
} | ||
} | ||
@@ -56,3 +76,16 @@ async addPayment(opts) { | ||
} | ||
async calculateTotalPaidAmount(cart) { | ||
if (!cart.paymentInfo || cart.paymentInfo.payments.length === 0) { | ||
return 0; | ||
} | ||
const payments = await Promise.all(cart.paymentInfo.payments.map((p) => this.ctAPI.payment.getPaymentById(p.id))); | ||
return payments.reduce((total, payment) => total + this.calculatePaymentAmount(payment), 0); | ||
} | ||
calculatePaymentAmount(payment) { | ||
return payment.transactions | ||
.filter((transaction) => (transaction.state === 'Success' || transaction.state === 'Pending') && | ||
(transaction.type === 'Authorization' || transaction.type === 'Charge')) | ||
.reduce((total, transaction) => total + transaction.amount.centAmount, 0); | ||
} | ||
} | ||
exports.DefaultCartService = DefaultCartService; |
import { Payment, PaymentDraft } from '@commercetools/platform-sdk'; | ||
import { GetPayment, PaymentModificationValidation, PaymentModificationValidationResult, PaymentService, PaymentServiceOptions, UpdatePayment } from '../types/payment.type'; | ||
import { GetPayment, PaymentCancelAuthorizationValidation, PaymentChargeValidation, PaymentModificationValidationResult, PaymentRefundValidation, PaymentService, PaymentServiceOptions, UpdatePayment } from '../types/payment.type'; | ||
/** | ||
@@ -12,3 +12,5 @@ * This is the default implementation of the PaymentService interface. | ||
updatePayment(opts: UpdatePayment): Promise<Payment>; | ||
validatePaymentModification(opts: PaymentModificationValidation): PaymentModificationValidationResult; | ||
validatePaymentCancelAuthorization(opts: PaymentCancelAuthorizationValidation): PaymentModificationValidationResult; | ||
validatePaymentCharge(opts: PaymentChargeValidation): PaymentModificationValidationResult; | ||
validatePaymentRefund(opts: PaymentRefundValidation): PaymentModificationValidationResult; | ||
private consolidateUpdateActions; | ||
@@ -22,6 +24,3 @@ private populateSetInterfaceIdAction; | ||
private consolidateTransactionChanges; | ||
private validateCancelAuthorization; | ||
private validateCapturePayment; | ||
private validateRefundPayment; | ||
private calculateTotalAmount; | ||
} |
@@ -47,14 +47,55 @@ "use strict"; | ||
} | ||
validatePaymentModification(opts) { | ||
switch (opts.type) { | ||
case 'cancelAuthorization': | ||
return this.validateCancelAuthorization(opts.payment); | ||
case 'capturePayment': | ||
return this.validateCapturePayment(opts.payment, opts.amount); | ||
case 'refundPayment': | ||
return this.validateRefundPayment(opts.payment, opts.amount); | ||
default: | ||
throw new Error(`Invalid payment modification type: ${opts.type}`); | ||
validatePaymentCancelAuthorization(opts) { | ||
const totalAuthorized = this.calculateTotalAmount(opts.payment, 'Authorization', opts.payment.amountPlanned.currencyCode); | ||
if (totalAuthorized === 0) { | ||
return { isValid: false, reason: `No authorization transaction found for resource ${opts.payment.id}.` }; | ||
} | ||
const totalCaptured = this.calculateTotalAmount(opts.payment, 'Charge', opts.payment.amountPlanned.currencyCode); | ||
if (totalCaptured > 0) { | ||
return { isValid: false, reason: `Resource ${opts.payment.id} has already been charged.` }; | ||
} | ||
return { isValid: true }; | ||
} | ||
validatePaymentCharge(opts) { | ||
if (opts.payment.amountPlanned.currencyCode !== opts.amount.currencyCode) { | ||
return { | ||
isValid: false, | ||
reason: `Invalid currency ${opts.amount.currencyCode} for resource ${opts.payment.id}, expected ${opts.payment.amountPlanned.currencyCode}`, | ||
}; | ||
} | ||
const totalAuthorized = this.calculateTotalAmount(opts.payment, 'Authorization', opts.amount.currencyCode); | ||
if (totalAuthorized === 0) { | ||
return { isValid: false, reason: `No authorization transaction found for resource ${opts.payment.id}.` }; | ||
} | ||
const totalCaptured = this.calculateTotalAmount(opts.payment, 'Charge', opts.amount.currencyCode); | ||
const allowedAmount = totalAuthorized - totalCaptured; | ||
if (opts.amount.centAmount > allowedAmount) { | ||
return { | ||
isValid: false, | ||
reason: `The amount to capture ${opts.amount.centAmount} exceeds the allowed amount [${allowedAmount}]`, | ||
}; | ||
} | ||
return { isValid: true }; | ||
} | ||
validatePaymentRefund(opts) { | ||
if (opts.payment.amountPlanned.currencyCode !== opts.amount.currencyCode) { | ||
return { | ||
isValid: false, | ||
reason: `Invalid currency ${opts.amount.currencyCode} for resource ${opts.payment.id}, expected ${opts.payment.amountPlanned.currencyCode}`, | ||
}; | ||
} | ||
const totalCaptured = this.calculateTotalAmount(opts.payment, 'Charge', opts.amount.currencyCode); | ||
if (totalCaptured === 0) { | ||
return { isValid: false, reason: `No charge transaction found for resource ${opts.payment.id}.` }; | ||
} | ||
const totalRefunded = this.calculateTotalAmount(opts.payment, 'Refund', opts.amount.currencyCode); | ||
const allowedAmount = totalCaptured - totalRefunded; | ||
if (opts.amount.centAmount > allowedAmount) { | ||
return { | ||
isValid: false, | ||
reason: `The amount to refund ${opts.amount.centAmount} exceeds the allowed amount [${allowedAmount}]`, | ||
}; | ||
} | ||
return { isValid: true }; | ||
} | ||
consolidateUpdateActions(payment, updateInfo) { | ||
@@ -141,55 +182,2 @@ const actions = []; | ||
} | ||
validateCancelAuthorization(payment) { | ||
const totalAuthorized = this.calculateTotalAmount(payment, 'Authorization', payment.amountPlanned.currencyCode); | ||
if (totalAuthorized === 0) { | ||
return { isValid: false, reason: `No authorization transaction found for resource ${payment.id}.` }; | ||
} | ||
const totalCaptured = this.calculateTotalAmount(payment, 'Charge', payment.amountPlanned.currencyCode); | ||
if (totalCaptured > 0) { | ||
return { isValid: false, reason: `Resource ${payment.id} has already been charged.` }; | ||
} | ||
return { isValid: true }; | ||
} | ||
validateCapturePayment(payment, amount) { | ||
if (payment.amountPlanned.currencyCode !== amount.currencyCode) { | ||
return { | ||
isValid: false, | ||
reason: `Invalid currency ${amount.currencyCode} for resource ${payment.id}, expected ${payment.amountPlanned.currencyCode}`, | ||
}; | ||
} | ||
const totalAuthorized = this.calculateTotalAmount(payment, 'Authorization', amount.currencyCode); | ||
if (totalAuthorized === 0) { | ||
return { isValid: false, reason: `No authorization transaction found for resource ${payment.id}.` }; | ||
} | ||
const totalCaptured = this.calculateTotalAmount(payment, 'Charge', amount.currencyCode); | ||
const allowedAmount = totalAuthorized - totalCaptured; | ||
if (amount.centAmount > allowedAmount) { | ||
return { | ||
isValid: false, | ||
reason: `The amount to capture ${amount.centAmount} exceeds the allowed amount [${allowedAmount}]`, | ||
}; | ||
} | ||
return { isValid: true }; | ||
} | ||
validateRefundPayment(payment, amount) { | ||
if (payment.amountPlanned.currencyCode !== amount.currencyCode) { | ||
return { | ||
isValid: false, | ||
reason: `Invalid currency ${amount.currencyCode} for resource ${payment.id}, expected ${payment.amountPlanned.currencyCode}`, | ||
}; | ||
} | ||
const totalCaptured = this.calculateTotalAmount(payment, 'Charge', amount.currencyCode); | ||
if (totalCaptured === 0) { | ||
return { isValid: false, reason: `No charge transaction found for resource ${payment.id}.` }; | ||
} | ||
const totalRefunded = this.calculateTotalAmount(payment, 'Refund', amount.currencyCode); | ||
const allowedAmount = totalCaptured - totalRefunded; | ||
if (amount.centAmount > allowedAmount) { | ||
return { | ||
isValid: false, | ||
reason: `The amount to refund ${amount.centAmount} exceeds the allowed amount [${allowedAmount}]`, | ||
}; | ||
} | ||
return { isValid: true }; | ||
} | ||
calculateTotalAmount(payment, type, currencyCode) { | ||
@@ -196,0 +184,0 @@ return payment.transactions |
@@ -16,2 +16,3 @@ import { AuthorizationService, CommercetoolsToken } from '../types/authorization.type'; | ||
getAllowedPaymentMethodsFromSession(session: Session): string[]; | ||
getPaymentInterfaceFromSession(session: Session): string | undefined; | ||
} |
@@ -44,3 +44,6 @@ "use strict"; | ||
} | ||
getPaymentInterfaceFromSession(session) { | ||
return session.metadata?.paymentInterface; | ||
} | ||
} | ||
exports.DefaultSessionService = DefaultSessionService; |
@@ -19,4 +19,4 @@ import { Cart } from '@commercetools/platform-sdk'; | ||
getCart(opts: GetCart): Promise<Cart>; | ||
getPaymentAmount(opts: GetPaymentAmount): PaymentAmount; | ||
getPaymentAmount(opts: GetPaymentAmount): Promise<PaymentAmount>; | ||
addPayment(opts: AddPayment): Promise<Cart>; | ||
} |
@@ -31,7 +31,13 @@ import { Money, Payment, PaymentDraft, TransactionState, TransactionType } from '@commercetools/platform-sdk'; | ||
}; | ||
export type PaymentModificationValidation = { | ||
export type PaymentCancelAuthorizationValidation = { | ||
payment: Payment; | ||
}; | ||
export type PaymentChargeValidation = { | ||
payment: Payment; | ||
amount: Money; | ||
type: TransactionType; | ||
}; | ||
export type PaymentRefundValidation = { | ||
payment: Payment; | ||
amount: Money; | ||
}; | ||
export type PaymentModificationValidationResult = { | ||
@@ -48,3 +54,5 @@ isValid: boolean; | ||
updatePayment(opts: UpdatePayment): Promise<Payment>; | ||
validatePaymentModification(opts: PaymentModificationValidation): PaymentModificationValidationResult; | ||
validatePaymentCancelAuthorization(opts: PaymentCancelAuthorizationValidation): PaymentModificationValidationResult; | ||
validatePaymentCharge(opts: PaymentChargeValidation): PaymentModificationValidationResult; | ||
validatePaymentRefund(opts: PaymentRefundValidation): PaymentModificationValidationResult; | ||
} |
@@ -28,2 +28,3 @@ export type Session = { | ||
getAllowedPaymentMethodsFromSession(session: Session): string[]; | ||
getPaymentInterfaceFromSession(session: Session): string | undefined; | ||
} |
@@ -18,2 +18,3 @@ "use strict"; | ||
allowedPaymentMethods: this.sessionService.getAllowedPaymentMethodsFromSession(session), | ||
paymentInterface: this.sessionService.getPaymentInterfaceFromSession(session), | ||
}); | ||
@@ -20,0 +21,0 @@ } |
@@ -18,2 +18,3 @@ export interface AuthenticationManager { | ||
allowedPaymentMethods: string[]; | ||
paymentInterface?: string; | ||
}; | ||
@@ -20,0 +21,0 @@ export type Oauth2Principal = { |
{ | ||
"name": "@commercetools/connect-payments-sdk", | ||
"version": "0.0.7", | ||
"version": "0.1.0", | ||
"description": "Payment SDK for commercetools payment connectors", | ||
@@ -18,3 +18,3 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@commercetools/platform-sdk": "7.2.0-alpha.4", | ||
"@commercetools/platform-sdk": "7.3.0", | ||
"@commercetools/sdk-client-v2": "2.3.0", | ||
@@ -21,0 +21,0 @@ "jsonwebtoken": "9.0.2", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
96920
2549
+ Added@commercetools/platform-sdk@7.3.0(transitive)
- Removed@commercetools/platform-sdk@7.2.0-alpha.4(transitive)