{"id":50946102,"url":"https://github.com/globalpayments-samples/pay-by-link","last_synced_at":"2026-06-17T20:07:35.437Z","repository":{"id":317734817,"uuid":"1057567429","full_name":"globalpayments-samples/pay-by-link","owner":"globalpayments-samples","description":"Pay by Link implementation for Global Payments API Platform. Create secure payment links for remote transactions with multi-currency support.","archived":false,"fork":false,"pushed_at":"2026-05-21T13:12:06.000Z","size":315,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-21T21:58:39.647Z","etag":null,"topics":["api-platform","ecommerce","global-payments","lang-dotnet","lang-go","lang-java","lang-nodejs","lang-php","lang-python","multi-currency","pay-by-link","payment-links","payment-processing","remote-payments"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/globalpayments-samples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-09-15T23:02:06.000Z","updated_at":"2026-05-21T13:14:27.000Z","dependencies_parsed_at":"2025-10-02T19:11:57.878Z","dependency_job_id":"1952ca0c-fce1-434a-961f-65f1b145d89e","html_url":"https://github.com/globalpayments-samples/pay-by-link","commit_stats":null,"previous_names":["globalpayments-samples/pay-by-link"],"tags_count":0,"template":false,"template_full_name":"globalpayments-samples/starter-template","purl":"pkg:github/globalpayments-samples/pay-by-link","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/globalpayments-samples%2Fpay-by-link","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/globalpayments-samples%2Fpay-by-link/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/globalpayments-samples%2Fpay-by-link/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/globalpayments-samples%2Fpay-by-link/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/globalpayments-samples","download_url":"https://codeload.github.com/globalpayments-samples/pay-by-link/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/globalpayments-samples%2Fpay-by-link/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34463588,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-platform","ecommerce","global-payments","lang-dotnet","lang-go","lang-java","lang-nodejs","lang-php","lang-python","multi-currency","pay-by-link","payment-links","payment-processing","remote-payments"],"created_at":"2026-06-17T20:07:34.522Z","updated_at":"2026-06-17T20:07:35.432Z","avatar_url":"https://github.com/globalpayments-samples.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Global Payments Pay by Link\n\nThis repository provides comprehensive **Pay by Link** implementations using the Global Payments GP API across six programming languages. Pay by Link allows merchants to create secure payment links that can be shared with customers via email, SMS, or other channels, enabling remote payments without requiring customers to visit a physical location or website.\n\n## Available Implementations\n\n- [.NET Core](./dotnet/) - ([Preview](https://githubbox.com/globalpayments-samples/pay-by-link/tree/main/dotnet)) - ASP.NET Core web application\n- [Go](./go/) - ([Preview](https://githubbox.com/globalpayments-samples/pay-by-link/tree/main/go)) - Go HTTP server application\n- [Java](./java/) - ([Preview](https://githubbox.com/globalpayments-samples/pay-by-link/tree/main/java)) - Jakarta EE servlet-based web application\n- [Node.js](./nodejs/) - ([Preview](https://githubbox.com/globalpayments-samples/pay-by-link/tree/main/nodejs)) - Express.js web application\n- [PHP](./php/) - ([Preview](https://githubbox.com/globalpayments-samples/pay-by-link/tree/main/php)) - PHP web application\n- [Python](./python/) - ([Preview](https://githubbox.com/globalpayments-samples/pay-by-link/tree/main/python)) - Flask web application\n\n## Features\n\n### Core Pay by Link Functionality\n\n- **Payment Link Creation** - Generate secure, time-limited payment links\n- **Multi-Currency Support** - EUR, USD, GBP currency support\n- **Input Validation** - Comprehensive validation and sanitization\n- **Error Handling** - Standardized error responses across all languages\n- **GP API Integration** - Direct integration with Global Payments sandbox/production APIs\n\n### Implementation Features\n\n- **Consistent API** - Identical `/create-payment-link` endpoint across all languages\n- **Environment Configuration** - Secure credential management with `.env` files\n- **Responsive Frontend** - HTML forms with real-time validation\n- **Production Ready** - Comprehensive error handling and logging\n- **OWASP Compliant** - Input sanitization and security best practices\n\n## Payment Flow\n\nPay by Link is an asynchronous two-stage flow. The merchant creates the link server-side; the customer pays on a GP-hosted page with no merchant frontend involved.\n\n```mermaid\nsequenceDiagram\n    participant M as Merchant Backend\n    participant GP as GP API\n    participant C as Customer\n\n    M-\u003e\u003eGP: POST /create-payment-link\u003cbr/\u003e(amount, currency, reference)\n    GP--\u003e\u003eM: { paymentLink: \"https://pay.globalpay.com/lnk_xxx\" }\n    Note over M,C: Merchant shares link via email, SMS, or any channel\n    M-\u003e\u003eC: Payment link\n    C-\u003e\u003eGP: Opens payment link\n    GP--\u003e\u003eC: Hosted payment page (no merchant frontend)\n    C-\u003e\u003eGP: Submits card details\n    GP--\u003e\u003eC: Payment confirmation\n    GP--\u003e\u003eM: Webhook notification (status_url)\n```\n\n## Quick Start\n\n### 1. Choose Your Language\nNavigate to any implementation directory:\n```bash\ncd nodejs/    # Node.js with Express\ncd python/    # Python with Flask\ncd php/       # Native PHP\ncd java/      # Java with Jakarta EE\ncd dotnet/    # .NET Core\ncd go/        # Go HTTP server\n```\n\n### 2. Set Up Environment\n\nCopy the sample environment file and add your GP API credentials:\n\n```bash\ncp .env.sample .env\n```\n\nEdit `.env` with your actual GP API credentials:\n\n```env\n# GP API App Credentials (required for Pay by Link)\nGP_API_APP_ID=your_app_id_here\nGP_API_APP_KEY=your_app_key_here\n\n# Environment (sandbox or production)\nGP_API_ENVIRONMENT=sandbox\n```\n\n### 3. Install Dependencies\n\n**Node.js:**\n```bash\nnpm install\n```\n\n**Python:**\n```bash\npip install -r requirements.txt\n```\n\n**PHP:**\n```bash\ncomposer install\n```\n\n**Java:**\n```bash\nmvn clean install\n```\n\n**Go:**\n```bash\ngo mod download\n```\n\n**.NET:**\n```bash\ndotnet restore\n```\n\n### 4. Run the Server\n\n**Node.js:**\n```bash\nnpm start\n# or\nnode server.js\n```\n\n**Python:**\n```bash\npython server.py\n```\n\n**PHP:**\n```bash\nphp -S localhost:8000 -t .\n```\n\n**Java:**\n```bash\nmvn cargo:run\n```\n\n**Go:**\n```bash\ngo run main.go\n```\n\n**.NET:**\n```bash\ndotnet run\n```\n\n### 5. Test the Implementation\n\nVisit `http://localhost:8000` and create a test payment link:\n\n1. Enter amount in cents (e.g., 1000 = $10.00)\n2. Select currency (EUR, USD, GBP)\n3. Provide reference, name, and description\n4. Click \"Create Payment Link\"\n5. Copy the generated payment link to share with customers\n\n## API Endpoints\n\n### GET `/config`\n\nReturns configuration data for client-side use:\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"environment\": \"sandbox\",\n    \"supportedCurrencies\": [\"EUR\", \"USD\", \"GBP\"],\n    \"supportedPaymentMethods\": [\"CARD\"]\n  }\n}\n```\n\n### POST `/create-payment-link`\n\nCreates a new payment link. **Required fields:**\n\n- `amount` (integer) - Amount in cents\n- `currency` (string) - Currency code (EUR/USD/GBP)\n- `reference` (string) - Merchant reference\n- `name` (string) - Payment name/title\n- `description` (string) - Payment description\n\n**Success Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Payment link created successfully! Link ID: lnk_xxx\",\n  \"data\": {\n    \"paymentLink\": \"https://pay.sandbox.globalpay.com/link/lnk_xxx\",\n    \"linkId\": \"lnk_xxx\",\n    \"reference\": \"ORDER-123\",\n    \"amount\": 1000,\n    \"currency\": \"USD\"\n  }\n}\n```\n\n**Error Response:**\n```json\n{\n  \"success\": false,\n  \"message\": \"Payment link creation failed\",\n  \"error\": {\n    \"code\": \"MISSING_REQUIRED_FIELDS\",\n    \"details\": \"Missing required fields. Received: amount, currency\"\n  }\n}\n```\n\n## Test Cards\n\n| Brand | Number | CVV | Expiry |\n|-------|--------|-----|--------|\n| Visa | 4263 9826 4026 9299 | 123 | Any future |\n| Mastercard | 5425 2334 2424 1200 | 123 | Any future |\n\n\u003e Pay by Link generates a hosted payment page. Test cards work when completing payment through the generated link in sandbox mode.\n\n## Payment Link Configuration\n\nAll implementations create payment links with these settings:\n\n- **Type:** PAYMENT (single-use payment)\n- **Usage Mode:** SINGLE (one-time use)\n- **Usage Limit:** 1\n- **Expiration:** 10 days from creation\n- **Channel:** CNP (Card Not Present)\n- **Country:** GB (Great Britain)\n- **Shipping:** YES with 0 amount\n- **Payment Methods:** CARD only\n- **Notifications:**\n  - Return URL: `https://www.example.com/returnUrl`\n  - Status URL: `https://www.example.com/statusUrl`\n  - Cancel URL: `https://www.example.com/returnUrl`\n\n## Input Validation \u0026 Security\n\n### Reference Sanitization\n\nAll implementations sanitize the reference field using regex pattern `[^\\w\\s\\-#]` to remove potentially harmful characters, allowing only:\n- Word characters (letters, digits, underscore)\n- Spaces, hyphens, and hash symbols\n- Limited to 100 characters maximum\n\n### Field Validation\n\n- **Amount:** Must be positive integer (cents)\n- **Currency:** Must be one of EUR, USD, GBP\n- **Name:** Trimmed and limited to 100 characters\n- **Description:** Trimmed and limited to 500 characters\n- **Reference:** Sanitized and limited to 100 characters\n\n## Error Handling\n\nStandardized error codes across all implementations:\n\n- `MISSING_REQUIRED_FIELDS` - Required fields missing from request\n- `INVALID_AMOUNT` - Amount is not a positive integer\n- `TOKEN_GENERATION_ERROR` - Failed to generate GP API access token\n- `API_ERROR` - GP API request failed\n- `INVALID_RESPONSE` - Unexpected response format from GP API\n- `UNKNOWN_ERROR` - Unexpected system error\n\n## Prerequisites\n\n- **Global Payments Account** with GP API credentials\n- **Development Environment** for your chosen language\n- **Package Manager** (npm, pip, composer, maven, dotnet, go)\n- **GP API Credentials:**\n  - App ID (`GP_API_APP_ID`)\n  - App Key (`GP_API_APP_KEY`)\n\n## Production Deployment\n\n### Environment Variables\n\nSet production environment variables:\n\n```env\nGP_API_APP_ID=your_production_app_id\nGP_API_APP_KEY=your_production_app_key\nGP_API_ENVIRONMENT=production\n```\n\n### Security Considerations\n\n- **Use HTTPS** for all production deployments\n- **Validate inputs** on both client and server side\n- **Log transactions** for audit and debugging\n- **Monitor failed requests** for potential issues\n- **Rate limit** the API endpoints\n- **Secure credential storage** using environment variables or secrets management\n\n### URL Configuration\n\nUpdate notification URLs in production:\n\n```javascript\nnotifications: {\n  return_url: \"https://yourdomain.com/payment-return\",\n  status_url: \"https://yourdomain.com/payment-webhook\",\n  cancel_url: \"https://yourdomain.com/payment-cancel\"\n}\n```\n\n## Architecture Notes\n\n### Direct API vs SDK\n\n- **SDK Implementations:** PHP, Java, .NET (use official Global Payments SDKs with `PayByLinkService`)\n- **Direct API Implementations:** Python, Node.js, Go (use direct HTTP calls to `https://apis.sandbox.globalpay.com/ucp/links`)\n- **Consistency:** All implementations achieve identical functionality regardless of approach\n\n### Technical Implementation Details\n\n**SDK Approach (PHP, Java, .NET):**\n- Uses official Global Payments SDK packages (`globalpayments/api`, `globalpayments-sdk`, `GlobalPayments.Api`)\n- SDK handles authentication token generation automatically\n- Provides type-safe `PayByLinkData` objects and `PayByLinkService` classes\n- Built-in error handling with SDK-specific exception types\n- Automatic API endpoint routing based on environment configuration\n\n**Direct API Approach (Python, Node.js, Go):**\n- Makes raw HTTP POST requests to Global Payments REST endpoints\n- Handles authentication token generation manually\n- Constructs JSON payloads directly\n- Processes HTTP responses and error handling manually\n- Examples: Python (requests), Go (net/http), Node.js (fetch/axios)\n\n\n### Response Format\n\nAll implementations return identical JSON response formats to ensure consistent client-side handling across different backend languages.\n\n### Error Handling Strategy\n\nEach implementation includes try-catch blocks with specific error categorization, ensuring consistent error reporting and debugging capabilities.\n\n## Community\n\n- 🌐 **Developer Portal** — [developer.globalpayments.com](https://developer.globalpayments.com)\n- 💬 **Discord** — [Join the community](https://discord.gg/myER9G9qkc)\n- 📋 **GitHub Discussions** — [github.com/orgs/globalpayments/discussions](https://github.com/orgs/globalpayments/discussions)\n- 📧 **Newsletter** — [Subscribe](https://www.globalpayments.com/en-gb/modals/newsletter)\n- 💼 **LinkedIn** — [Global Payments for Developers](https://www.linkedin.com/showcase/global-payments-for-developers/posts/?feedView=all)\n\nHave a question or found a bug? [Open an issue](https://github.com/globalpayments-samples/pay-by-link/issues) or reach out at [communityexperience@globalpay.com](mailto:communityexperience@globalpay.com).\n\n## License\n\nThis project is licensed under the MIT License - see individual implementation directories for specific license details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglobalpayments-samples%2Fpay-by-link","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglobalpayments-samples%2Fpay-by-link","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglobalpayments-samples%2Fpay-by-link/lists"}