mirror of
https://github.com/duhanbalci/iyzico.git
synced 2026-03-03 20:29:18 +00:00
374 lines
12 KiB
TypeScript
374 lines
12 KiB
TypeScript
/**
|
|
* Payment integration tests
|
|
*/
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import { createTestClient, assertSuccessResponse } from '../setup';
|
|
import { testNon3DPaymentRequest, test3DSInitializeRequest } from '../fixtures/payment';
|
|
import { IyzicoResponseError } from '../../src/errors';
|
|
|
|
describe('Payment Integration Tests', () => {
|
|
const client = createTestClient();
|
|
|
|
it('should create a non-3DS payment', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-non3ds-${Date.now()}`,
|
|
};
|
|
|
|
const response = await client.payment.createNon3DS(request);
|
|
|
|
assertSuccessResponse(response);
|
|
expect(response.paymentId).toBeTruthy();
|
|
expect(response.price).toBe(request.price);
|
|
});
|
|
|
|
it('should get payment detail by paymentId', async () => {
|
|
// First create a payment
|
|
const paymentRequest = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-detail-${Date.now()}`,
|
|
};
|
|
|
|
const paymentResponse = await client.payment.createNon3DS(paymentRequest);
|
|
assertSuccessResponse(paymentResponse);
|
|
|
|
if (!paymentResponse.paymentId) {
|
|
throw new Error('Payment ID is required for detail test');
|
|
}
|
|
|
|
// Then get payment detail
|
|
const detailResponse = await client.payment.getDetail({
|
|
paymentId: paymentResponse.paymentId,
|
|
locale: 'tr',
|
|
});
|
|
|
|
assertSuccessResponse(detailResponse);
|
|
expect(detailResponse.paymentId).toBe(paymentResponse.paymentId);
|
|
});
|
|
|
|
it('should initialize 3DS payment', async () => {
|
|
const request = {
|
|
...test3DSInitializeRequest,
|
|
conversationId: `test-3ds-init-${Date.now()}`,
|
|
};
|
|
|
|
const response = await client.payment.initialize3DS(request);
|
|
|
|
assertSuccessResponse(response);
|
|
expect(response.paymentId).toBeTruthy();
|
|
expect(response.htmlContent || response.threeDSHtmlContent).toBeTruthy();
|
|
});
|
|
|
|
it('should complete 3DS v1 payment', async () => {
|
|
// First initialize a 3DS payment
|
|
const initRequest = {
|
|
...test3DSInitializeRequest,
|
|
conversationId: `test-3ds-v1-${Date.now()}`,
|
|
};
|
|
|
|
const initResponse = await client.payment.initialize3DS(initRequest);
|
|
assertSuccessResponse(initResponse);
|
|
|
|
if (!initResponse.paymentId) {
|
|
throw new Error('Payment ID is required for 3DS completion test');
|
|
}
|
|
|
|
// In sandbox, 3DS completion will fail without actual 3DS flow
|
|
// We expect an IyzicoResponseError to be thrown
|
|
await expect(
|
|
client.payment.complete3DS({
|
|
paymentId: initResponse.paymentId,
|
|
locale: 'tr',
|
|
conversationId: `test-3ds-v1-complete-${Date.now()}`,
|
|
})
|
|
).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should complete 3DS v2 payment', async () => {
|
|
// First initialize a 3DS payment
|
|
const initRequest = {
|
|
...test3DSInitializeRequest,
|
|
conversationId: `test-3ds-v2-${Date.now()}`,
|
|
};
|
|
|
|
const initResponse = await client.payment.initialize3DS(initRequest);
|
|
assertSuccessResponse(initResponse);
|
|
|
|
if (!initResponse.paymentId) {
|
|
throw new Error('Payment ID is required for 3DS completion test');
|
|
}
|
|
|
|
// In sandbox, 3DS completion will fail without actual 3DS flow
|
|
// We expect an IyzicoResponseError to be thrown
|
|
await expect(
|
|
client.payment.complete3DSV2({
|
|
paymentId: initResponse.paymentId,
|
|
locale: 'tr',
|
|
conversationId: `test-3ds-v2-complete-${Date.now()}`,
|
|
paidPrice: initRequest.paidPrice,
|
|
basketId: initRequest.basketId!,
|
|
currency: initRequest.currency || 'TRY',
|
|
})
|
|
).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
describe('Edge Cases - Invalid Fields', () => {
|
|
it('should handle missing required fields (price)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-missing-price-${Date.now()}`,
|
|
price: undefined as any,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle missing required fields (paidPrice)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-missing-paidprice-${Date.now()}`,
|
|
paidPrice: undefined as any,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle missing required fields (paymentCard)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-missing-card-${Date.now()}`,
|
|
paymentCard: undefined as any,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle missing required fields (buyer)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-missing-buyer-${Date.now()}`,
|
|
buyer: undefined as any,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle missing required fields (billingAddress)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-missing-billing-${Date.now()}`,
|
|
billingAddress: undefined as any,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle missing required fields (basketItems)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-missing-basket-${Date.now()}`,
|
|
basketItems: undefined as any,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle empty basketItems array', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-empty-basket-${Date.now()}`,
|
|
basketItems: [],
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid card number (too short)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-card-short-${Date.now()}`,
|
|
paymentCard: {
|
|
...testNon3DPaymentRequest.paymentCard,
|
|
cardNumber: '1234',
|
|
},
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid card number (non-numeric)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-card-nonnumeric-${Date.now()}`,
|
|
paymentCard: {
|
|
...testNon3DPaymentRequest.paymentCard,
|
|
cardNumber: 'ABCDEFGHIJKLMNOP',
|
|
},
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid expiry month (invalid format)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-expmonth-${Date.now()}`,
|
|
paymentCard: {
|
|
...testNon3DPaymentRequest.paymentCard,
|
|
expireMonth: '13',
|
|
},
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid expiry year (invalid format)', async () => {
|
|
// Note: Sandbox doesn't validate past years, so we test invalid format instead
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-expyear-format-${Date.now()}`,
|
|
paymentCard: {
|
|
...testNon3DPaymentRequest.paymentCard,
|
|
expireYear: 'AB', // Invalid format - non-numeric
|
|
},
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid CVV (too short)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-cvv-short-${Date.now()}`,
|
|
paymentCard: {
|
|
...testNon3DPaymentRequest.paymentCard,
|
|
cvc: '12',
|
|
},
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid CVV (non-numeric)', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-cvv-nonnumeric-${Date.now()}`,
|
|
paymentCard: {
|
|
...testNon3DPaymentRequest.paymentCard,
|
|
cvc: 'ABC',
|
|
},
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle negative price', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-negative-price-${Date.now()}`,
|
|
price: -100.0,
|
|
paidPrice: -100.0,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle zero price', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-zero-price-${Date.now()}`,
|
|
price: 0,
|
|
paidPrice: 0,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid currency', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-currency-${Date.now()}`,
|
|
currency: 'INVALID' as any,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid installment value', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-installment-${Date.now()}`,
|
|
installment: 99 as any,
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid email format', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-invalid-email-${Date.now()}`,
|
|
buyer: {
|
|
...testNon3DPaymentRequest.buyer,
|
|
email: 'invalid-email-format',
|
|
},
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle basket item with negative price', async () => {
|
|
const request = {
|
|
...testNon3DPaymentRequest,
|
|
conversationId: `test-negative-basket-price-${Date.now()}`,
|
|
basketItems: [
|
|
{
|
|
...testNon3DPaymentRequest.basketItems[0],
|
|
price: -10.0,
|
|
},
|
|
],
|
|
};
|
|
|
|
await expect(client.payment.createNon3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle missing callbackUrl for 3DS initialize', async () => {
|
|
const request = {
|
|
...test3DSInitializeRequest,
|
|
conversationId: `test-missing-callback-${Date.now()}`,
|
|
callbackUrl: undefined as any,
|
|
};
|
|
|
|
await expect(client.payment.initialize3DS(request)).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle invalid paymentId for getDetail', async () => {
|
|
await expect(
|
|
client.payment.getDetail({
|
|
paymentId: 'invalid-payment-id-12345',
|
|
locale: 'tr',
|
|
})
|
|
).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle empty paymentId for getDetail', async () => {
|
|
await expect(
|
|
client.payment.getDetail({
|
|
paymentId: '',
|
|
locale: 'tr',
|
|
})
|
|
).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
|
|
it('should handle missing paymentId and paymentConversationId for getDetail', async () => {
|
|
await expect(
|
|
client.payment.getDetail({
|
|
locale: 'tr',
|
|
})
|
|
).rejects.toThrow(IyzicoResponseError);
|
|
});
|
|
});
|
|
});
|
|
|