Job Description
This is a remote position.
We are looking for a Senior Node.js Developer to join our product engineering team building a SaaS product that integrates deeply with Coupa and other enterprise applications. The ideal candidate will have strong hands-on expertise in Node.js, TypeScript, PostgreSQL, REST APIs, data transformation, and enterprise integrations, with practical experience working with Coupa or similar procurement/ERP platforms. This is a WFH position.
Required Qualifications
- 4+ years of professional software development experience building production-grade backend systems — ideally SaaS products or enterprise integration platforms, not just prototypes.
- Strong hands-on expertise in Node.js, TypeScript/JavaScript, and SQL against PostgreSQL.
- Solid grounding in software architecture, API design, error handling/logging, and production troubleshooting.
- Experience writing automated unit and integration tests for backend services.
- Hands-on experience building or supporting integrations with Coupa (or a comparable enterprise procurement/ERP platform) via REST/JSON APIs, including authentication, request/response handling, and error handling.
- Working knowledge of core procurement objects and flows (suppliers, requisitions, purchase orders, invoices, receipts) sufficient to reason about integration behavior.
- Proven experience with data mapping, transformation, validation, and synchronization between source and target systems, and the ability to independently scope an integration's API calls, mappings, and error handling from a requirement.
- Experience troubleshooting integration failures using logs, API payloads, and database records.
- Experience with Git-based workflows: pull requests, branching, and code review.
- Ability to read and troubleshoot CI/CD pipeline failures.
- Hands-on AWS experience, including containerized deployments (ECS or equivalent, with underlying Docker knowledge), CloudWatch, and S3.
- Experience supporting customer-facing implementations or integrations, and distinguishing customer-specific configuration issues from product-level defects.
- Excellent written and verbal English, with the ability to produce clear defect write-ups, technical specs, and runbooks.
- Hands-on experience with AI-assisted development tools (e.g., Claude Code, GitHub Copilot, Cursor), and able to describe how you use them while maintaining code quality and review standards.
Preferred Qualifications
- Experience building a commercial SaaS product rather than working exclusively on individual customer integrations.
- Deep experience with Coupa integration architecture and Coupa APIs.
- Experience integrating Coupa with NetSuite, Sage Intacct, Microsoft Dynamics, SAP, Oracle, or other ERP platforms.
- Experience with Coupa customers, Coupa implementation partners, or Coupa's integration ecosystem, including working directly with Coupa Support to escalate platform-side issues.
- Experience designing multi-tenant SaaS integrations where a single product supports different customer configurations and integration requirements.
- Experience with Node.js async/queue-based patterns (e.g., BullMQ, AWS SQS), webhooks, scheduled integrations, retry mechanisms, and idempotency for high-volume enterprise data synchronization.
- Familiarity with observability/APM tooling beyond CloudWatch (e.g., Datadog, New Relic, Sentry).
- Familiarity with enterprise security practices: OAuth2, credentials/secrets management (e.g., AWS Secrets Manager or Parameter Store), audit logging, and compliance requirements.
- Experience working under formal change management, release management, audit, security, or compliance processes.
- Experience with embedded, docked, plug-in, or extensible application architectures.
- Basic procurement/accounting literacy (PO matching, GL coding, tax/currency handling) relevant to invoice and PO data mapping.
check(event) ; career-website-detail-template-2 => apply(record.id,meta)" mousedown="lyte-button => check(event)" final-style="background-color:#CC440E;border-color:#CC440E;color:white;" final-class="lyte-button lyteBackgroundColorBtn lyteSuccess" lyte-rendered="">