From 07b10f6145dd86df17bf736e9e3c830af3681234 Mon Sep 17 00:00:00 2001 From: vamsii777 Date: Mon, 17 Feb 2025 22:45:03 +0530 Subject: [PATCH] Add documentation for Razorpay SDK Create comprehensive documentation for the Razorpay Swift SDK, including: - Getting Started guide - Order creation documentation - Payment processing guide - Refund handling documentation - Add .spi.yml configuration for documentation targets --- .spi.yml | 4 + .../Razorpay/Razorpay.docc/CreatingOrders.md | 141 ++++++++++ .../Razorpay/Razorpay.docc/Documentation.md | 245 ++++++++++++++++++ .../Razorpay/Razorpay.docc/GettingStarted.md | 98 +++++++ .../Razorpay/Razorpay.docc/HandlingRefunds.md | 186 +++++++++++++ .../Razorpay.docc/ProcessingPayments.md | 187 +++++++++++++ 6 files changed, 861 insertions(+) create mode 100644 .spi.yml create mode 100644 Sources/Razorpay/Razorpay.docc/CreatingOrders.md create mode 100644 Sources/Razorpay/Razorpay.docc/Documentation.md create mode 100644 Sources/Razorpay/Razorpay.docc/GettingStarted.md create mode 100644 Sources/Razorpay/Razorpay.docc/HandlingRefunds.md create mode 100644 Sources/Razorpay/Razorpay.docc/ProcessingPayments.md diff --git a/.spi.yml b/.spi.yml new file mode 100644 index 0000000..9cc13f3 --- /dev/null +++ b/.spi.yml @@ -0,0 +1,4 @@ +version: 1 +builder: + configs: + - documentation_targets: [Razorpay, RazorpayKit] \ No newline at end of file diff --git a/Sources/Razorpay/Razorpay.docc/CreatingOrders.md b/Sources/Razorpay/Razorpay.docc/CreatingOrders.md new file mode 100644 index 0000000..ca48be3 --- /dev/null +++ b/Sources/Razorpay/Razorpay.docc/CreatingOrders.md @@ -0,0 +1,141 @@ +# Creating Orders + +Learn how to create and manage orders in Razorpay. + +## Overview + +Orders are the foundation of the payment process in Razorpay. An order represents the intent to collect payment and must be created before accepting payments from customers. + +## Creating Orders + +### Basic Order Creation + +Create a simple order with just the required fields: + +```swift +let orderRequest = OrderRequest( + amount: 100000, // ₹1000.00 in paise + currency: "INR" +) +``` + +### Advanced Order Creation + +Include additional details for better tracking and management: + +```swift +let orderRequest = OrderRequest( + amount: 100000, + currency: "INR", + receipt: "order_rcptid_123", + notes: [ + "customer_name": "John Doe", + "customer_email": "john@example.com" + ], + partialPayment: true, + firstPaymentMinAmount: 50000 +) +``` + +## Order Properties + +- `amount`: Payment amount in smallest currency unit (paise for INR) +- `currency`: Three-letter ISO currency code +- `receipt`: Your system's order reference +- `notes`: Additional information as key-value pairs +- `partialPayment`: Enable/disable partial payments +- `firstPaymentMinAmount`: Minimum amount for first partial payment + +## Handling Responses + +### Successful Order Creation + +```swift +client.createOrder(orderRequest) { result in + switch result { + case .success(let order): + print("Order ID: \(order.id)") + print("Amount: \(order.amount)") + print("Currency: \(order.currency)") + print("Receipt: \(order.receipt ?? "Not provided")") + print("Status: \(order.status)") + case .failure(let error): + handleError(error) + } +} +``` + +### Order Status + +Track the order status through its lifecycle: + +```swift +client.fetchOrder(orderId) { result in + switch result { + case .success(let order): + switch order.status { + case .created: + print("Order is created") + case .attempted: + print("Payment attempted") + case .paid: + print("Payment successful") + } + case .failure(let error): + handleError(error) + } +} +``` + +## Best Practices + +### Amount Handling + +Always convert amount to smallest currency unit: + +```swift +func convertToSmallestUnit(_ amount: Double, currency: String) -> Int { + switch currency { + case "INR": + return Int(amount * 100) // Convert to paise + default: + return Int(amount * 100) // Default to smallest unit + } +} + +// Usage +let amount = convertToSmallestUnit(1000.00, currency: "INR") +``` + +### Error Handling + +Implement robust error handling: + +```swift +func handleError(_ error: Error) { + if let razorpayError = error as? RazorpayError { + switch razorpayError { + case .invalidRequest(let message): + print("Invalid request: \(message)") + case .authenticationError: + print("Authentication failed") + case .serverError(let message): + print("Server error: \(message)") + } + } +} +``` + +## Topics + +### Essential Order Operations + +- ``OrderRequest`` +- ``OrderResponse`` +- ``OrderResponse/Status`` + +### Related Types + +- ``Payment`` +- ``RazorpayClient`` +- ``RazorpayError`` \ No newline at end of file diff --git a/Sources/Razorpay/Razorpay.docc/Documentation.md b/Sources/Razorpay/Razorpay.docc/Documentation.md new file mode 100644 index 0000000..58c2d7c --- /dev/null +++ b/Sources/Razorpay/Razorpay.docc/Documentation.md @@ -0,0 +1,245 @@ +# ``Razorpay`` + +A Swift package that provides a type-safe interface to interact with the Razorpay payment gateway. + +## Overview + +The Razorpay Swift package provides a comprehensive set of tools and models to integrate Razorpay payment gateway into your iOS or macOS applications. It offers type-safe APIs for creating orders, processing payments, and handling various payment-related operations. + +## Installation + +You can add Razorpay as a dependency to your project using Swift Package Manager: + +```swift +dependencies: [ + .package(url: "https://github.com/vamsii777/razorpay-kit.git", from: "1.0.0") +] +``` + +## Topics + +### Essentials + +- +- ``RazorpayClient`` + +### Payment Processing + +- ``Payment`` +- ``OrderRequest`` +- ``OrderResponse`` + +### Models + +- ``Payment/Status`` +- ``Payment/Method`` +- ``Payment/RefundStatus`` +- ``Payment/UPIDetails`` +- ``Payment/Card`` +- ``Payment/EMIDetails`` +- ``OrderResponse/Status`` + +### Error Handling + +- ``RazorpayError`` + +### Articles + +- +- +- + +# Getting Started + +@Metadata { + @PageKind(article) +} + +## Creating a Razorpay Client + +To get started with the Razorpay SDK, create a client instance with your API credentials: + +```swift +let client = RazorpayClient( + keyId: "your_key_id", + keySecret: "your_key_secret" +) +``` + +## Creating an Order + +Create a new order using the `OrderRequest` model: + +```swift +let orderRequest = OrderRequest( + amount: 100000, // Amount in paise (₹1000.00) + currency: "INR", + receipt: "order_123", + notes: ["customer_name": "John Doe"] +) + +client.createOrder(orderRequest) { result in + switch result { + case .success(let order): + print("Order created: \(order.id)") + case .failure(let error): + print("Error: \(error)") + } +} +``` + +## Processing Payments + +Once an order is created, you can process payments using various payment methods: + +```swift +// Fetch payment details +client.fetchPayment("payment_id") { result in + switch result { + case .success(let payment): + print("Payment status: \(payment.status)") + case .failure(let error): + print("Error: \(error)") + } +} +``` + +## Error Handling + +The SDK provides comprehensive error handling through the `RazorpayError` type: + +```swift +if let error = error as? RazorpayError { + switch error { + case .invalidRequest(let message): + print("Invalid request: \(message)") + case .authenticationError: + print("Authentication failed") + case .serverError(let message): + print("Server error: \(message)") + } +} +``` + +# Creating Orders + +@Metadata { + @PageKind(article) +} + +## Overview + +Orders are the first step in the payment process. An order represents the intent to collect payment and contains information about the amount, currency, and other optional details. + +## Creating a Basic Order + +```swift +let orderRequest = OrderRequest( + amount: 100000, + currency: "INR" +) +``` + +## Adding Optional Details + +You can include additional information with your order: + +```swift +let orderRequest = OrderRequest( + amount: 100000, + currency: "INR", + receipt: "order_123", + notes: ["customer_name": "John Doe"], + partialPayment: true, + firstPaymentMinAmount: 50000 +) +``` + +## Handling Order Response + +The order response contains important information about the created order: + +```swift +client.createOrder(orderRequest) { result in + switch result { + case .success(let order): + print("Order ID: \(order.id)") + print("Amount: \(order.amount)") + print("Status: \(order.status)") + case .failure(let error): + print("Error: \(error)") + } +} +``` + +# Processing Payments + +@Metadata { + @PageKind(article) +} + +## Overview + +The Razorpay SDK supports various payment methods including cards, UPI, netbanking, and wallets. + +## Payment Methods + +### Card Payments + +```swift +let cardDetails = Card( + number: "4111111111111111", + expiryMonth: "12", + expiryYear: "24", + cvv: "123" +) +``` + +### UPI Payments + +```swift +let upiDetails = UPIDetails( + vpa: "user@upi" +) +``` + +## Handling Payment Response + +```swift +client.fetchPayment(paymentId) { result in + switch result { + case .success(let payment): + if payment.status == .captured { + print("Payment successful") + } + case .failure(let error): + print("Payment failed: \(error)") + } +} +``` + +# Handling Refunds + +@Metadata { + @PageKind(article) +} + +## Overview + +The SDK provides functionality to process full and partial refunds for payments. + +## Processing Refunds + +```swift +client.refundPayment( + paymentId: "pay_123", + amount: 50000 // Partial refund of ₹500 +) { result in + switch result { + case .success(let refund): + print("Refund processed: \(refund.id)") + case .failure(let error): + print("Refund failed: \(error)") + } +} +``` \ No newline at end of file diff --git a/Sources/Razorpay/Razorpay.docc/GettingStarted.md b/Sources/Razorpay/Razorpay.docc/GettingStarted.md new file mode 100644 index 0000000..0cf2ea7 --- /dev/null +++ b/Sources/Razorpay/Razorpay.docc/GettingStarted.md @@ -0,0 +1,98 @@ +# Getting Started with Razorpay + +Learn how to integrate Razorpay into your Swift application. + +## Overview + +This guide walks you through the basic setup and initial steps to start accepting payments using the Razorpay Swift SDK. + +## Setting Up Your Environment + +### Prerequisites + +Before you begin, make sure you have: + +- A Razorpay account with API credentials +- Xcode 13.0 or later +- iOS 13.0 or later / macOS 10.15 or later + +### Installation + +Add Razorpay to your project using Swift Package Manager: + +```swift +dependencies: [ + .package(url: "https://github.com/vamsii777/razorpay-kit.git", from: "1.0.0") +] +``` + +## Basic Configuration + +### Initialize the Client + +Create a Razorpay client instance with your API credentials: + +```swift +import Razorpay + +let client = RazorpayClient( + keyId: "your_key_id", + keySecret: "your_key_secret" +) +``` + +### Creating Your First Order + +1. Create an order request: + +```swift +let orderRequest = OrderRequest( + amount: 100000, // Amount in paise (₹1000.00) + currency: "INR", + receipt: "order_123" +) +``` + +2. Submit the order: + +```swift +client.createOrder(orderRequest) { result in + switch result { + case .success(let order): + print("Order created: \(order.id)") + // Present payment options to user + case .failure(let error): + print("Error: \(error)") + } +} +``` + +## Best Practices + +- Always store API credentials securely +- Handle errors gracefully +- Validate amounts before creating orders +- Implement proper error handling +- Use appropriate currency codes + +## Next Steps + +- Learn about different payment methods +- Implement webhooks for payment notifications +- Set up recurring payments +- Handle refunds + +## Topics + +### Essentials + +- +- +- + +### Related Types + +- ``RazorpayClient`` +- ``OrderRequest`` +- ``OrderResponse`` +- ``Payment`` \ No newline at end of file diff --git a/Sources/Razorpay/Razorpay.docc/HandlingRefunds.md b/Sources/Razorpay/Razorpay.docc/HandlingRefunds.md new file mode 100644 index 0000000..9ca7f30 --- /dev/null +++ b/Sources/Razorpay/Razorpay.docc/HandlingRefunds.md @@ -0,0 +1,186 @@ +# Handling Refunds + +Learn how to process and manage refunds for payments made through Razorpay. + +## Overview + +The Razorpay SDK provides comprehensive support for processing refunds, both full and partial. This guide covers the various aspects of handling refunds in your application. + +## Processing Refunds + +### Full Refund + +Process a full refund for a payment: + +```swift +client.refundPayment( + paymentId: "pay_123" +) { result in + switch result { + case .success(let refund): + print("Refund processed: \(refund.id)") + print("Amount refunded: \(refund.amount)") + case .failure(let error): + handleRefundError(error) + } +} +``` + +### Partial Refund + +Process a partial refund with specific amount: + +```swift +client.refundPayment( + paymentId: "pay_123", + amount: 50000, // ₹500.00 in paise + notes: ["reason": "Customer request"] +) { result in + switch result { + case .success(let refund): + handleSuccessfulRefund(refund) + case .failure(let error): + handleRefundError(error) + } +} +``` + +## Refund Status + +### Checking Refund Status + +Monitor the status of a refund: + +```swift +client.fetchRefund( + paymentId: "pay_123", + refundId: "rfnd_123" +) { result in + switch result { + case .success(let refund): + switch refund.status { + case .processed: + print("Refund processed") + case .processing: + print("Refund in progress") + case .failed: + print("Refund failed") + } + case .failure(let error): + handleRefundError(error) + } +} +``` + +### Listing All Refunds + +Fetch all refunds for a payment: + +```swift +client.fetchAllRefunds( + paymentId: "pay_123" +) { result in + switch result { + case .success(let refunds): + for refund in refunds { + print("Refund ID: \(refund.id)") + print("Amount: \(refund.amount)") + print("Status: \(refund.status)") + } + case .failure(let error): + handleRefundError(error) + } +} +``` + +## Handling Responses + +### Successful Refund + +Handle successful refund response: + +```swift +func handleSuccessfulRefund(_ refund: Refund) { + // Update UI + updateRefundStatus(refund.status) + + // Store refund details + saveRefundDetails( + refundId: refund.id, + amount: refund.amount, + status: refund.status + ) + + // Notify user + notifyRefundSuccess(refund) +} +``` + +### Error Handling + +Implement robust error handling: + +```swift +func handleRefundError(_ error: Error) { + if let razorpayError = error as? RazorpayError { + switch razorpayError { + case .invalidRequest(let message): + showError("Invalid refund request: \(message)") + case .authenticationError: + showError("Authentication failed") + case .serverError(let message): + showError("Refund processing error: \(message)") + } + } +} +``` + +## Best Practices + +### Amount Validation + +Validate refund amount before processing: + +```swift +func validateRefundAmount( + refundAmount: Int, + paymentAmount: Int +) -> Bool { + // Check if refund amount is valid + guard refundAmount > 0 else { + return false + } + + // Check if refund amount doesn't exceed payment amount + guard refundAmount <= paymentAmount else { + return false + } + + return true +} +``` + +### Refund Notes + +Add detailed notes for better tracking: + +```swift +let refundNotes: [String: String] = [ + "reason": "Customer dissatisfied", + "request_date": ISO8601DateFormatter().string(from: Date()), + "requested_by": "support_agent_123" +] +``` + +## Topics + +### Essential Refund Operations + +- ``Refund`` +- ``Refund/Status`` +- ``Payment`` + +### Related Types + +- ``RazorpayClient`` +- ``RazorpayError`` \ No newline at end of file diff --git a/Sources/Razorpay/Razorpay.docc/ProcessingPayments.md b/Sources/Razorpay/Razorpay.docc/ProcessingPayments.md new file mode 100644 index 0000000..4d612a1 --- /dev/null +++ b/Sources/Razorpay/Razorpay.docc/ProcessingPayments.md @@ -0,0 +1,187 @@ +# Processing Payments + +Learn how to process payments using various payment methods in Razorpay. + +## Overview + +The Razorpay SDK supports multiple payment methods including cards, UPI, netbanking, and wallets. This guide explains how to implement and handle different payment methods. + +## Payment Methods + +### Card Payments + +Process credit and debit card payments: + +```swift +let cardDetails = Card( + number: "4111111111111111", + expiryMonth: "12", + expiryYear: "24", + cvv: "123", + name: "John Doe" +) + +client.processCardPayment( + orderId: "order_123", + card: cardDetails +) { result in + switch result { + case .success(let payment): + handleSuccessfulPayment(payment) + case .failure(let error): + handlePaymentError(error) + } +} +``` + +### UPI Payments + +Process UPI payments using VPA (Virtual Payment Address): + +```swift +let upiDetails = UPIDetails( + vpa: "user@upi" +) + +client.processUPIPayment( + orderId: "order_123", + upi: upiDetails +) { result in + switch result { + case .success(let payment): + handleSuccessfulPayment(payment) + case .failure(let error): + handlePaymentError(error) + } +} +``` + +### Netbanking + +Process payments through netbanking: + +```swift +client.processNetbankingPayment( + orderId: "order_123", + bankCode: "HDFC" +) { result in + switch result { + case .success(let payment): + handleSuccessfulPayment(payment) + case .failure(let error): + handlePaymentError(error) + } +} +``` + +## Payment Status + +### Checking Payment Status + +Monitor the status of a payment: + +```swift +client.fetchPayment(paymentId) { result in + switch result { + case .success(let payment): + switch payment.status { + case .created: + print("Payment initiated") + case .authorized: + print("Payment authorized") + case .captured: + print("Payment captured") + case .refunded: + print("Payment refunded") + case .failed: + print("Payment failed") + } + case .failure(let error): + handlePaymentError(error) + } +} +``` + +### Handling Payment Response + +Process payment response and update UI: + +```swift +func handleSuccessfulPayment(_ payment: Payment) { + // Update UI + updatePaymentStatus(payment.status) + + // Store payment details + savePaymentDetails( + paymentId: payment.id, + amount: payment.amount, + method: payment.method + ) + + // Trigger success callback + notifyPaymentSuccess(payment) +} + +func handlePaymentError(_ error: Error) { + if let razorpayError = error as? RazorpayError { + switch razorpayError { + case .invalidRequest(let message): + showError("Invalid payment details: \(message)") + case .authenticationError: + showError("Payment authentication failed") + case .serverError(let message): + showError("Payment processing error: \(message)") + } + } +} +``` + +## Payment Verification + +### Verifying Payment Signature + +Verify payment signature to ensure authenticity: + +```swift +let signature = "razorpay_signature" +let orderId = "order_123" +let paymentId = "pay_123" + +client.verifyPaymentSignature( + orderId: orderId, + paymentId: paymentId, + signature: signature +) { isValid in + if isValid { + print("Payment signature verified") + } else { + print("Invalid payment signature") + } +} +``` + +## Best Practices + +- Always verify payment signatures +- Implement proper error handling +- Store payment details securely +- Update UI promptly with payment status +- Handle network errors gracefully +- Implement retry logic for failed payments +- Log payment events for debugging + +## Topics + +### Essential Payment Operations + +- ``Payment`` +- ``Payment/Status`` +- ``Payment/Method`` +- ``Payment/Card`` +- ``Payment/UPIDetails`` + +### Related Types + +- ``RazorpayClient`` +- ``RazorpayError`` +- ``OrderResponse`` \ No newline at end of file