{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Line of Credit Migration Guide","siteUrl":"https://docs.peachfinance.com","description":"API and product documentation for Peach Finance, a lending-as-a-service platform.","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"line-of-credit-migration-guide","__idx":0},"children":["Line of Credit Migration Guide"]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"introduction","__idx":1},"children":["Introduction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This guide provides end-to-end instructions on how to migrate an existing line of credit (LOC) portfolio from your legacy system to Peach, i.e., preparing your data, creating borrowers and loans, populating historical records, executing the migration, and validating results."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["LOC migration uses a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["statement-based approach"]},". Historical data before the most recent statement date is stored as read-only snapshots. Data after that date is actively replayed by Peach's Loan Replay™ engine. This differs from installment loan migration, which recreates the full loan history from activation."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-loc-migration-differs-from-installment-migration","__idx":2},"children":["How LOC migration differs from installment migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before diving into the steps, it helps to understand how LOC migration compares to installment loan migration at a high level."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Aspect"},"children":["Aspect"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Installment loan"},"children":["Installment loan"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Line of credit"},"children":["Line of credit"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["History handling"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Full replay from activation date"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Read-only history before cutoff; replay after"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Object structure"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Single loan object"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Line (loan) + multiple draws + migration draw"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration timing"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Any time"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Between statement date and due date"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Balance calculation"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Fully recalculated from scratch"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Seeded from statement balances"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Historical objects"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Expected payments"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Past periods, purchases, past transactions (optional — see note below)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Replay behavior"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["All events replayed chronologically"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Only activities after cutoff date replayed"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," Past periods, historical purchases, and past transactions are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not required"]}," for migration to succeed. They are read-only objects that display the borrower's history for convenience and reference, but they do not affect balance calculations or loan behavior. It is possible to migrate a loan onto Peach with just the seed balances and overdue information, and the loan will start running as if it was just created with those balances. However, providing historical data is recommended for a complete borrower experience."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The key difference is the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["migration cutoff date"]},". For LOCs, Peach does not recalculate balances from the beginning of the loan. Instead, you provide balance snapshots as of the most recent statement date, and Peach replays only the activity that occurred after that date. This makes LOC migration faster but requires accurate statement-date balances from your legacy system. You will also need very granular information about your draws — since Peach allows draws with different interest rates, fee structures, and configurations, you must provide balances broken down by draw so Peach knows which balance belongs to which draw."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"key-concepts","__idx":3},"children":["Key concepts"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["These terms appear throughout the guide. Understanding them before you start will make each step clearer."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"migration-period","__idx":4},"children":["Migration period"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The loan period during which migration executes. It begins on the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["migration cutoff date"]}," (your most recent statement date) and ends on the last day of that billing cycle. This is the \"live\" period — Peach takes control of the loan starting from the migration period's start date."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example:"]}," If your statement generates on the 1st of each month and payment is due on the 22nd:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Previous period: Jul 1 – Jul 31 (statement date: Aug 1, due date: Aug 22)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Migration period: Aug 1 – Aug 31 (statement date: Sep 1, due date: Sep 22)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," Migration must complete before the previous period's due date that falls within the migration period. In this example, that means migration must finish before ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Aug 22"]},". If it doesn't, the loan must be canceled and re-migrated. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#canceling-and-re-migrating-loans"},"children":["Canceling and re-migrating loans"]}," for the recovery process."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["What happens if you miss the migration deadline:"]}," If migration is not completed before the previous period's due date, there is currently no in-place recovery path. You must cancel the loan (clearing external IDs), then restart the migration process from the beginning. When you re-create the loan, the data from the original migration period moves into \"past periods\" (read-only history), and you set up a new migration period based on your next statement date. Note that there is no time limit on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]}," phase — you can remain in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]}," for as long as needed while preparing your data. The deadline only applies to when you call the migrate endpoint."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"migration-cutoff-date","__idx":5},"children":["Migration cutoff date"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The most recent statement date relative to the day you execute migration. This date divides all activity into two categories:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Before the cutoff date"]}," → historical (read-only). Stored as past periods and past transactions."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["On or after the cutoff date"]}," → live. Replayed by Peach during migration."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["All balances you provide to Peach must be accurate ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["as of"]}," this date. The cutoff date is also the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startDate"]}," of the migration period."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," Balances should include interest accrued through the last day of the previous period (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate"]},") but should ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," include interest for the statement date itself. Peach's system will accrue interest for the statement date during the migration replay. If you include interest for the statement date in your seed balances, the consequence is double interest corresponding to that day."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"migration-draw-static-draw","__idx":6},"children":["Migration draw (static draw)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you create a line of credit with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus: \"prepMigration\""]},", Peach automatically creates a special draw called the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["migration draw"]},". This draw serves as a container for all historical activity that occurred before the migration cutoff date."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The migration draw has specific behaviors:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["All historical purchases are posted to this draw (with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originalDrawId"]}," field referencing the actual legacy draw)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["It does ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," accrue interest."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["It does ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," participate in the Loan Replay process."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["After migration completes, it transitions to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["active"]}," status but is effectively disabled — no new activity can be posted to it. The API rejects requests targeting a static draw."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Static draw post-migration behavior:"]}," After migration completes, the migration draw receives ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["active"]}," status but is functionally inert. It does not participate in fee caps or other calculations that aggregate across draws. All new activity (purchases, payments, fees) must be posted to the actual draws you create in Step 2."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"past-periods-data","__idx":7},"children":["Past periods data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Statement-cycle snapshots from your legacy system, covering the borrower's full history before the migration cutoff date. Each past period includes start/end dates, statement date, due date, and optionally a reference to the uploaded statement document."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Past periods are displayed in the borrower's history but are not replayed — they're read-only records."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"historical-vs-live-activity","__idx":8},"children":["Historical vs. live activity"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Activity is categorized based on when it occurred relative to the migration cutoff date:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":""},"children":[]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Historical activity"},"children":["Historical activity"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Live activity"},"children":["Live activity"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["When it occurred"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Before migration cutoff date"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["On or after migration cutoff date"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Where purchases go"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration draw (with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originalDrawId"]},")"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Actual draw"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Transaction endpoint"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../migration/past-transaction"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../transactions"]}," (with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isExternal: true"]},")"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fee endpoint"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../fees"]}," (with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.originalDrawId"]},")"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../fees"]}," (normal)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Replayed by Peach?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Yes"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"grace-period-eligibility","__idx":9},"children":["Grace period eligibility"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For LOC products with grace periods (common for credit cards), the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isGracePeriodEligible"]}," field in the migration period data controls whether interest accrues during the migration period:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," → No interest accrues during the migration period (borrower is in grace)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," → Interest begins accruing immediately from the cutoff date."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Grace eligibility is re-evaluated on the day after the due date within the migration period. This means the system checks whether the borrower paid the full statement balance by the due date, and updates grace status accordingly for the next period."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Edge case:"]}," If a draw is configured with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]}," greater than 1 (meaning the borrower must pay in full for multiple consecutive periods to regain grace), this rule is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not enforced during the migration period"]},". During migration, if the draw qualifies for grace based on the current period's payment, the system restores grace immediately — regardless of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]},". This is by design: since Peach does not store per-draw grace history for past periods, it defaults to the behavior most favorable to the borrower. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]}," rule takes full effect starting in the period after the migration period."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":10},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Complete these steps before beginning the migration process."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1-set-up-a-sandbox-environment","__idx":11},"children":["1. Set up a sandbox environment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create or confirm access to a Peach sandbox environment. You'll use the sandbox to test the full migration workflow with sample loans before running in production."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," Sandbox has capacity limits. Migrate no more than ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["5 loans at a time"]}," in sandbox. Exceeding this limit may cause significant processing delays or migration failures."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2-configure-your-loan-type","__idx":12},"children":["2. Configure your loan type"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create or confirm a Loan Type for your LOC product. The Loan Type defines interest calculation methods, fee structures, payment schedules, and other product-level rules. You'll reference the Loan Type ID (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanTypeId"]},") when creating each loan."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3-configure-fee-types","__idx":13},"children":["3. Configure fee types"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If your LOC product charges dynamic fees (late fees, annual fees, draw fees, foreign transaction fees, modification fees), ensure each fee type is configured in Peach with a Fee Type ID. You'll reference these IDs when creating fees during migration."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fee type guidance:"]}," Configure the fee types you want Peach to charge going forward with the correct settings. Once the loan migrates, Peach will continue charging these fees according to the loan type configuration. It is also possible to post live fees on the loan during the replay period, so configure fee types that match your production fee structure as closely as possible."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"4-prepare-your-legacy-data","__idx":14},"children":["4. Prepare your legacy data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Extract the following data from your legacy system. You'll need it throughout the migration process:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Borrower data:"]}," Name, date of birth, SSN/identity, contact information (addresses, emails, phone numbers), consent records"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Loan terms:"]}," Original activation date, credit limit, interest rates (including promo rates if applicable), APR, payment frequency, due date schedule, grace period terms, minimum payment calculation rules"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Statement history:"]}," Start/end dates, statement dates, due dates, and statement balances for each historical billing cycle"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Draw data:"]}," Active draws with their individual credit limits, interest rates, and balances"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purchase history:"]}," Every purchase with date, amount, merchant details, draw association, and current status"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Transaction history:"]}," Every payment, service credit, and down payment with date, amount, payment instrument, status, and draw allocation"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fee history:"]}," Every fee charged with type, amount, date, and associated draw/purchase"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Balance snapshot as of the migration cutoff date:"]}," Current balances broken down by due/non-due/overdue for both the line level and each draw, including principal, interest, and each fee type"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Delinquency data:"]}," Days past due, overdue amounts, date from which account is overdue (if applicable)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Payment instruments:"]}," Active and historical bank accounts, cards, and other payment methods"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"5-plan-your-migration-timing","__idx":15},"children":["5. Plan your migration timing"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Migration must be executed within a specific window:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["earliest"]}," you can migrate is immediately after the migration cutoff date (your most recent statement date)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["latest"]}," you should migrate is before the previous period's due date that falls within the migration period."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["There is no time limit on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]}," phase — you can remain in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]}," for as long as needed while you prepare and validate your data. The timing window above applies only to when you call the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /migrate"]}," endpoint."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example timeline:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The previous period runs from Jul 1 through Jul 31"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The statement date is Aug 1"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The due date is Aug 22"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The migration period runs from Aug 1 through Aug 31"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In this scenario, the earliest you can migrate is Aug 1 (the cutoff date, which is the most recent statement date). The latest you should migrate is before Aug 22 (the previous period's due date, which falls within the migration period)."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-create-the-borrower-and-payment-methods","__idx":16},"children":["Step 1: Create the borrower and payment methods"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Establish the borrower's identity and payment capabilities in Peach."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-borrower","__idx":17},"children":["Create borrower"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create a borrower record with personal information. You'll use the returned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["personId"]}," in all subsequent API calls."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people\nContent-Type: application/json\n\n{\n  \"status\": \"active\",\n  \"externalId\": \"your-borrower-id-123\",\n  \"name\": {\n    \"firstName\": \"Jane\",\n    \"middleName\": \"A\",\n    \"lastName\": \"Smith\"\n  },\n  \"dateOfBirth\": \"1985-03-15\",\n  \"identity\": {\n    \"identityType\": \"SSN\",\n    \"value\": \"123456789\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Response"]}," (abbreviated):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"data\": {\n    \"id\": \"BO-1234-ABCD\",\n    \"externalId\": \"your-borrower-id-123\",\n    \"status\": \"active\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-contact-records","__idx":18},"children":["Create contact records"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create separate contact records for each piece of contact information. This separation enables contact-level management and history tracking."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/contacts\nContent-Type: application/json\n\n{\n  \"contactType\": \"address\",\n  \"label\": \"home\",\n  \"affiliation\": \"self\",\n  \"status\": \"primary\",\n  \"address\": {\n    \"addressLine1\": \"742 Evergreen Terrace\",\n    \"city\": \"San Francisco\",\n    \"state\": \"CA\",\n    \"postalCode\": \"94105\",\n    \"country\": \"US\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Repeat for each email address, phone number, and additional address. Each contact record includes a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contactType"]}," (address, email, phone), a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["label"]}," (home, work, mobile), and an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["affiliation"]}," (self, spouse, etc.)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-payment-instruments","__idx":19},"children":["Create payment instruments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create payment instruments for both active and historical payment methods. Active methods will be used for future payments; historical methods are needed for accurate transaction records."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Active payment instrument"]}," (full account details):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/payment-instruments\nContent-Type: application/json\n\n{\n  \"status\": \"active\",\n  \"verified\": true,\n  \"nickname\": \"Primary Checking\",\n  \"instrumentType\": \"bankAccount\",\n  \"accountNumber\": \"9876543210\",\n  \"routingNumber\": \"021000021\",\n  \"accountType\": \"checking\",\n  \"accountHolderType\": \"personal\",\n  \"accountHolderName\": \"Jane A Smith\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Historical payment instrument"]}," (last four digits only):"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For payment methods no longer in use, set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isExternal: true"]},". This requires only the last four digits of the account number."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/payment-instruments\nContent-Type: application/json\n\n{\n  \"status\": \"active\",\n  \"verified\": true,\n  \"isExternal\": true,\n  \"nickname\": \"Old Checking (closed)\",\n  \"instrumentType\": \"bankAccount\",\n  \"accountNumberLastFour\": \"5678\",\n  \"accountType\": \"checking\",\n  \"accountHolderType\": \"personal\",\n  \"accountHolderName\": \"Jane A Smith\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can also provide inline payment instrument details directly on migration transactions using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentInstrumentDetails"]},", which accepts the following types: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bankAccount"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["creditCard"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["debitCard"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["check"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payroll"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["moneyOrder"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["wire"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["custom"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," Only payment instruments with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status: \"active\""]}," can be used for future payments. Historical instruments created with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isExternal: true"]}," are for record-keeping only."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2-create-and-configure-the-line-of-credit","__idx":20},"children":["Step 2: Create and configure the line of credit"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create the loan object, retrieve the auto-generated migration draw, create any additional active draws, and upload loan documents."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-the-loan","__idx":21},"children":["Create the loan"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create the line of credit with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status: \"pending\""]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.migrationStatus: \"prepMigration\""]},". The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["atOrigination"]}," object defines the loan's terms; the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration"]}," object tells Peach this loan is being migrated."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans\nContent-Type: application/json\n\n{\n  \"externalId\": \"your-loc-id-789\",\n  \"loanTypeId\": \"LT-LOC-ABCD\",\n  \"type\": \"lineOfCredit\",\n  \"servicedBy\": \"creditor\",\n  \"status\": \"pending\",\n  \"muteLoanNotices\": true,\n  \"atOrigination\": {\n    \"paymentFrequency\": \"monthly\",\n    \"specificDays\": [22],\n    \"interestRates\": [\n      { \"days\": null, \"rate\": 0.1999 }\n    ],\n    \"promoRates\": [],\n    \"aprEffective\": 0.2149,\n    \"aprNominal\": 0.1999,\n    \"creditLimitAmount\": 10000.00,\n    \"gracePeriod\": {\n      \"enabled\": true,\n      \"numDays\": 25,\n      \"numPeriodsToRestoreGrace\": 1\n    },\n    \"minPaymentCalculation\": {\n      \"percentageOfPrincipal\": 0.02,\n      \"minAmount\": 25.00,\n      \"includeFeesInCalculation\": true,\n      \"includeInterestInCalculation\": true\n    },\n    \"personAddressId\": \"CT-ADDR-ABCD\",\n    \"skipCreditReporting\": false\n  },\n  \"migration\": {\n    \"migrationStatus\": \"prepMigration\",\n    \"activatedDate\": \"2023-06-15\",\n    \"activatedTimeOfDay\": {\n      \"hour\": 10,\n      \"minute\": 0,\n      \"second\": 0\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Response"]}," (abbreviated):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"data\": {\n    \"id\": \"LN-1234-ABCD\",\n    \"type\": \"lineOfCredit\",\n    \"status\": \"pending\",\n    \"migrationStatus\": \"prepMigration\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," Setting ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["muteLoanNotices: true"]}," is not strictly required — Peach will not send borrower notifications during the migration process. However, setting it to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," provides an extra safeguard and gives you explicit control over when communications resume after migration. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#re-enable-borrower-communications"},"children":["Borrower communications during migration"]}," for details."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key fields in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["atOrigination"]},":"]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentFrequency"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specificDays"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Current billing frequency and due date day(s) of month. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specificDays"]}," must align with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}," in the migration period data — e.g., if ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}," is the 22nd, set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specificDays: [22]"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["interestRates"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Interest rate schedule. Set from the migration cutoff date. Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["days: null"]}," for an indefinite rate."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["promoRates"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Promotional rate schedule, if applicable"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["creditLimitAmount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Credit limit at origination"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gracePeriod"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Grace period configuration. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numDays"]}," is the number of days after the statement date during which no interest accrues if the full balance is paid."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["minPaymentCalculation"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Rules for calculating the minimum payment each cycle"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["skipCreditReporting"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," if you do not report this loan to credit bureaus"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key fields in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration"]},":"]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Must be ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"prepMigration\""]}," to begin the process"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["activatedDate"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The original date the line of credit was opened in your legacy system"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["activatedTimeOfDay"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Time of activation (hour, minute, second in product timezone)"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"retrieve-the-migration-draw","__idx":22},"children":["Retrieve the migration draw"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you create a loan with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus: \"prepMigration\""]},", Peach automatically creates the migration draw. Retrieve it to get its ID — you'll need this when posting historical purchases and fees."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"GET /api/people/{personId}/loans/{loanId}/draws\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Response"]}," (abbreviated):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"data\": [\n    {\n      \"id\": \"DR-MIGR-ABCD\",\n      \"nickname\": \"Migration Draw\",\n      \"drawType\": \"static\",\n      \"status\": \"pending\"\n    }\n  ]\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The migration draw has ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawType: \"static\""]},". Save this ID for Step 4."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-active-draws","__idx":23},"children":["Create active draws"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create any draws that should exist after the migration cutoff date. These are the \"real\" draws that will be active post-migration — they accrue interest, accept new purchases, and participate in billing."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Only create draws that should be live after the cutoff date. Historical draws that have been closed or fully paid off don't need to be created as separate draws — their activity goes to the migration draw."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/draws\nContent-Type: application/json\n\n{\n  \"externalId\": \"your-draw-id-001\",\n  \"nickname\": \"Primary Draw\",\n  \"status\": \"pending\",\n  \"atOrigination\": {\n    \"interestRates\": [\n      { \"days\": null, \"rate\": 0.1999 }\n    ],\n    \"creditLimitAmount\": 8000.00,\n    \"minPaymentCalculation\": {\n      \"percentageOfPrincipal\": 0.02,\n      \"minAmount\": 25.00\n    },\n    \"gracePeriod\": {\n      \"enabled\": true,\n      \"numDays\": 25,\n      \"numPeriodsToRestoreGrace\": 1\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Response"]}," (abbreviated):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"data\": {\n    \"id\": \"DR-0001-ABCD\",\n    \"externalId\": \"your-draw-id-001\",\n    \"status\": \"pending\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Repeat for each active draw. Save each draw's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," — you'll need them for migration period data and live activities."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"upload-loan-documents","__idx":24},"children":["Upload loan documents"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload loan agreements, historical statements, and any other relevant documents. Create a document descriptor first, then upload the file content."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/documents\nContent-Type: application/json\n\n{\n  \"type\": \"loanAgreement\",\n  \"description\": \"Original LOC Agreement\",\n  \"status\": \"accepted\",\n  \"loanId\": \"LN-1234-ABCD\",\n  \"sensitiveData\": false\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/documents/{documentDescriptorId}/content\nContent-Type: multipart/form-data\n\nfile=@/path/to/agreement.pdf\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you're providing historical statements for past periods (Step 3), save each document descriptor ID — you'll reference it when creating past period data."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-3-populate-historical-data","__idx":25},"children":["Step 3: Populate historical data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Provide Peach with the borrower's historical billing cycles and set up the migration period with current balances. This step has three parts: past periods, migration period LOC data, and migration period draw data."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-past-periods-data","__idx":26},"children":["Create past periods data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Past periods are billing-cycle snapshots from your legacy system covering the borrower's history before the migration cutoff date. They appear in the borrower's statement history but are not replayed."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Period date rules:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Periods must be contiguous — no gaps between them. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startDate"]}," of each period must equal the day after the previous period's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]}," for each period must equal the day after the period's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}," must fall within the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["following"]}," period's date range."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No two periods can have overlapping start-end date ranges."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/migration/past-periods\nContent-Type: application/json\n\n[\n  {\n    \"startDate\": \"2024-04-01\",\n    \"endDate\": \"2024-04-30\",\n    \"statementDate\": \"2024-05-01\",\n    \"dueDate\": \"2024-05-22\",\n    \"statement\": {\n      \"documentDescriptorId\": \"DD-APR-ABCD\",\n      \"creditBalanceAmount\": 0.00,\n      \"minimumAmountDue\": 125.00,\n      \"newBalanceAmount\": 3450.75\n    },\n    \"gracePeriod\": {\n      \"fullBalanceAmount\": 3450.75,\n      \"fullBalanceMinusOverdueAmount\": 3450.75,\n      \"isGracePeriodEligible\": true\n    }\n  },\n  {\n    \"startDate\": \"2024-05-01\",\n    \"endDate\": \"2024-05-31\",\n    \"statementDate\": \"2024-06-01\",\n    \"dueDate\": \"2024-06-22\",\n    \"statement\": {\n      \"documentDescriptorId\": \"DD-MAY-ABCD\",\n      \"creditBalanceAmount\": 0.00,\n      \"minimumAmountDue\": 118.50,\n      \"newBalanceAmount\": 3200.00\n    },\n    \"gracePeriod\": {\n      \"fullBalanceAmount\": 3200.00,\n      \"fullBalanceMinusOverdueAmount\": 3200.00,\n      \"isGracePeriodEligible\": true\n    }\n  }\n]\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Include all historical periods from the loan's activation through the period immediately before the migration period. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statement.documentDescriptorId"]}," is optional — include it if you uploaded the corresponding statement document."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Grace period fields in past periods:"]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fullBalanceAmount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Total balance eligible for grace period evaluation"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fullBalanceMinusOverdueAmount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Full balance minus any overdue amount"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["totalFulfilledOnDueDateAmount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Amount paid by the due date. Set this on the period one day after the due date."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isGracePeriodEligible"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Whether the borrower maintained grace eligibility through this period"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-migration-period-loc-data","__idx":27},"children":["Create migration period LOC data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The migration period LOC data represents the line-level state as of the migration cutoff date. This is where you provide the balance snapshot and obligation information that Peach uses as its starting point."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/migration/period\nContent-Type: application/json\n\n{\n  \"startDate\": \"2024-08-01\",\n  \"endDate\": \"2024-08-31\",\n  \"statementDate\": \"2024-09-01\",\n  \"dueDate\": \"2024-09-22\",\n  \"balances\": {\n    \"nonDueBalances\": {\n      \"nonDueOriginationFeesAmount\": 0.00,\n      \"nonDueLateFeesAmount\": 0.00\n    },\n    \"dueBalances\": {\n      \"dueOriginationFeesAmount\": 0.00,\n      \"dueLateFeesAmount\": 0.00\n    },\n    \"overdueBalances\": {\n      \"overdueOriginationFeesAmount\": 0.00,\n      \"overdueLateFeesAmount\": 0.00\n    },\n    \"creditLimitAmount\": 10000.00,\n    \"reimbursementAmount\": 0.00\n  },\n  \"obligation\": {\n    \"obligationAmount\": 125.00,\n    \"migratedDaysOverdue\": 0,\n    \"migratedOverdueFromDate\": null\n  },\n  \"gracePeriod\": {\n    \"isGracePeriodEligible\": true,\n    \"fullBalanceAmount\": 2850.00,\n    \"fullBalanceMinusOverdueAmount\": 2850.00\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Balance fields at the line level"]}," include only origination fees and late fees broken down by non-due, due, and overdue. The line level can only carry fee balances — principal and interest balances are tracked at the draw level, not the line level. Do not post principal or interest balance totals on the line."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["creditLimitAmount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Current overall credit limit for the line"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["reimbursementAmount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Amount the lender owes to the borrower (credit balances). Set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0.00"]}," if not applicable."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["obligation.obligationAmount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Remaining amount the borrower must pay by the upcoming due date"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["obligation.migratedDaysOverdue"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Number of days the account was overdue as of the cutoff date. Set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]}," if current."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["obligation.migratedOverdueFromDate"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Date from which the account has been overdue. Set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," if the account is current, ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["or"]}," if the overdue date is the same as the migration cutoff date. For example, if you are migrating on 2/1, the migration cutoff is 2/1, and the loan is overdue 7 days, you can set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedOverdueFromDate"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedDaysOverdue"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["7"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," All balance amounts must be ≥ 0.00 with a precision of 0.01 (two decimal places)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-migration-period-draw-data","__idx":28},"children":["Create migration period draw data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["each active draw"]}," (not the migration draw), create migration period data with draw-level balances and obligations."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/draws/{drawId}/migration/period\nContent-Type: application/json\n\n{\n  \"balances\": {\n    \"nonDueBalances\": {\n      \"nonDuePrincipalAmount\": 2200.00,\n      \"nonDueInterestAmount\": 0.00,\n      \"nonDueDrawFeesAmount\": 0.00,\n      \"nonDueLateFeesAmount\": 0.00,\n      \"nonDueModificationFeesAmount\": 0.00\n    },\n    \"dueBalances\": {\n      \"duePrincipalAmount\": 50.00,\n      \"dueInterestAmount\": 37.50,\n      \"dueDrawFeesAmount\": 0.00,\n      \"dueLateFeesAmount\": 0.00,\n      \"dueModificationFeesAmount\": 0.00\n    },\n    \"overdueBalances\": {\n      \"overduePrincipalAmount\": 0.00,\n      \"overdueInterestAmount\": 0.00,\n      \"overdueDrawFeesAmount\": 0.00,\n      \"overdueLateFeesAmount\": 0.00,\n      \"overdueModificationFeesAmount\": 0.00\n    },\n    \"creditLimitAmount\": 8000.00\n  },\n  \"obligation\": {\n    \"obligationAmount\": 87.50,\n    \"migratedDaysOverdue\": 0\n  },\n  \"gracePeriod\": {\n    \"isGracePeriodEligible\": true,\n    \"fullBalanceAmount\": 2287.50,\n    \"fullBalanceMinusOverdueAmount\": 2287.50\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Draw-level balances provide a more granular breakdown than line-level balances, including principal, interest, draw fees, late fees, and modification fees for each draw."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Late fees vs. modification fees:"]}," Peach maintains separate ledger buckets for late fees and modification fees. You must specify which fee type each balance belongs to — the system needs to know the correct ledger bucket for each amount. Ensure your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["lateFeesAmount"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["modificationFeesAmount"]}," fields accurately reflect the fee type from your legacy system."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Repeat this call for every active draw. Note that line-level and draw-level balances are independent — the line level only carries fee balances (origination fees, late fees), while draws carry principal, interest, and draw-specific fees. Do not attempt to reconcile draw-level totals against line-level totals, as there is validation that prevents the line from having principal or interest balances. Similarly, the sum of draw-level ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["creditLimitAmount"]}," values should not exceed the line-level credit limit."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"change-loan-status-to-originated","__idx":29},"children":["Change loan status to Originated"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After populating all historical data, change the loan status from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originated"]},". This locks the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["atOrigination"]}," data."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"PUT /api/people/{personId}/loans/{loanId}\nContent-Type: application/json\n\n{\n  \"status\": \"originated\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," After changing status to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originated"]},", you cannot modify the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["atOrigination"]}," object. Make sure all loan terms, interest rates, and configuration are correct before this step."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-4-create-activities","__idx":30},"children":["Step 4: Create activities"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create all purchases, transactions (payments), and fees — both historical and live. The distinction between historical and live determines which endpoint you use and which draw receives the activity."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"historical-purchases-before-the-migration-cutoff-date","__idx":31},"children":["Historical purchases (before the migration cutoff date)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Post historical purchases to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["migration draw"]},", not to the actual draws. Use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.originalDrawId"]}," field to record which legacy draw the purchase originally belonged to. This enables proper balance adjustments if the purchase is later disputed."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/draws/{migrationDrawId}/purchases\nContent-Type: application/json\n\n{\n  \"externalId\": \"your-purchase-id-001\",\n  \"type\": \"regular\",\n  \"status\": \"settled\",\n  \"amount\": 249.99,\n  \"purchaseDate\": \"2024-07-10\",\n  \"purchaseDetails\": {\n    \"description\": \"Electronics Store\",\n    \"pointOfSaleType\": \"inStore\",\n    \"merchantName\": \"Best Buy #1234\",\n    \"merchantNumber\": \"MRC-9876\"\n  },\n  \"migration\": {\n    \"originalDrawId\": \"your-legacy-draw-id-001\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," Purchases in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authorized"]}," status are not allowed in past periods (before the migration cutoff date). All historical purchases must have a terminal status such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["settled"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["canceled"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["returned"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"live-purchases-on-or-after-the-migration-cutoff-date","__idx":32},"children":["Live purchases (on or after the migration cutoff date)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Post live purchases to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["actual draw"]}," they belong to. Do not include the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration"]}," object."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/draws/{drawId}/purchases\nContent-Type: application/json\n\n{\n  \"externalId\": \"your-purchase-id-042\",\n  \"type\": \"regular\",\n  \"status\": \"settled\",\n  \"amount\": 75.50,\n  \"purchaseDate\": \"2024-08-05\",\n  \"purchaseDetails\": {\n    \"description\": \"Grocery Store\",\n    \"pointOfSaleType\": \"inStore\",\n    \"merchantName\": \"Whole Foods #567\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"historical-transactions-before-the-migration-cutoff-date","__idx":33},"children":["Historical transactions (before the migration cutoff date)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["migration-specific past-transaction endpoint"]}," for payments that occurred before the cutoff date. Include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," to record how the payment was allocated across draws — this is essential for handling reversals or status changes after migration."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/migration/past-transaction\nContent-Type: application/json\n\n{\n  \"externalId\": \"your-payment-id-001\",\n  \"amount\": 200.00,\n  \"type\": \"oneTimePayment\",\n  \"status\": \"succeeded\",\n  \"effectiveDate\": \"2024-07-22\",\n  \"effectiveTimeOfDay\": {\n    \"hour\": 14,\n    \"minute\": 30,\n    \"second\": 0\n  },\n  \"paymentInstrumentId\": \"PI-1234-ABCD\",\n  \"migration\": {\n    \"drawSplitDetails\": [\n      {\n        \"originalDrawId\": \"your-legacy-draw-id-001\",\n        \"drawAllocatedAmount\": 200.00\n      }\n    ]\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Transaction types supported:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["oneTimePayment"]}," — Standard payment"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["serviceCredit"]}," — Credit applied to the account (note: you cannot pass ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]}," for service credits — the system automatically sets it to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["succeeded"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["downPayment"]}," — Down payment"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Status options"]}," (for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["oneTimePayment"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["downPayment"]},"): ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["initiated"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["succeeded"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["canceled"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inDispute"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["chargeback"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," are critical for post-migration modifications."]}," If you need to change a historical transaction's status after migration (e.g., from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["succeeded"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},"), Peach uses the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," to determine which draw balances to adjust. If you omit ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]},", post-migration status changes on that transaction will fail."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Important constraints:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Only reference ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["active draw IDs"]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," — do ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," use the migration draw ID."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," are only returned by the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../migration/past-transaction"]}," endpoint, not the standard ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../transactions"]}," endpoint."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Inline payment instrument details:"]}," If you don't want to create a separate payment instrument record for a historical transaction, you can provide details inline:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"paymentInstrumentDetails\": {\n    \"type\": \"bankAccount\",\n    \"accountLastFour\": \"5678\",\n    \"customDisplayName\": \"Legacy Checking\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"live-transactions-on-or-after-the-migration-cutoff-date","__idx":34},"children":["Live transactions (on or after the migration cutoff date)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["standard transaction endpoint"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isExternal: true"]}," for payments processed by your legacy system after the cutoff date."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/transactions\nContent-Type: application/json\n\n{\n  \"externalId\": \"your-payment-id-042\",\n  \"paymentInstrumentId\": \"PI-1234-ABCD\",\n  \"amount\": 150.00,\n  \"type\": \"oneTime\",\n  \"status\": \"succeeded\",\n  \"isExternal\": true,\n  \"effectiveDate\": \"2024-08-15\",\n  \"effectiveTimeOfDay\": {\n    \"hour\": 10,\n    \"minute\": 0,\n    \"second\": 0\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type"]}," field differs between endpoints: the past-transaction endpoint uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["oneTimePayment"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["serviceCredit"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["downPayment"]},", while the standard transaction endpoint uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["oneTime"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["serviceCredit"]},", etc. Use the correct type value for the endpoint you're calling."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effectiveTimeOfDay"]}," must be after 2:00 AM in the product timezone. Transactions with earlier times will fail validation."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"historical-fees-before-the-migration-cutoff-date","__idx":35},"children":["Historical fees (before the migration cutoff date)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create fees using the standard fee endpoint, but include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.originalDrawId"]}," to associate the fee with the correct legacy draw. For purchase-related fees (e.g., foreign transaction fees), also include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.originalPurchaseId"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/fees\nContent-Type: application/json\n\n{\n  \"feeTypeId\": \"FT-LATE-ABCD\",\n  \"amount\": 29.00,\n  \"chargeDate\": \"2024-07-25\",\n  \"chargeTimeOfDay\": {\n    \"hour\": 10,\n    \"minute\": 0,\n    \"second\": 0\n  },\n  \"migration\": {\n    \"originalDrawId\": \"your-legacy-draw-id-001\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fee types with special migration fields:"]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Fee type"},"children":["Fee type"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Additional migration field"},"children":["Additional migration field"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Late fees, annual fees"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.originalDrawId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Associates with a legacy draw. Omit for line-level fees."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["NSF fees"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.originalTransactionId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Associates with the failed transaction"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Foreign transaction fees"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.originalPurchaseId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Associates with the purchase that triggered the fee"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"live-fees-on-or-after-the-migration-cutoff-date","__idx":36},"children":["Live fees (on or after the migration cutoff date)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create live fees normally, without the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration"]}," object."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/fees\nContent-Type: application/json\n\n{\n  \"feeTypeId\": \"FT-LATE-ABCD\",\n  \"amount\": 29.00,\n  \"chargeDate\": \"2024-08-25\",\n  \"chargeTimeOfDay\": {\n    \"hour\": 10,\n    \"minute\": 0,\n    \"second\": 0\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-5-execute-migration","__idx":37},"children":["Step 5: Execute migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With all data in place, trigger the migration process. Peach validates the prepared data, replays live activities, and activates the loan."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"call-the-migrate-endpoint","__idx":38},"children":["Call the migrate endpoint"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/migrate\nContent-Type: application/json\n\n{\n  \"sync\": false\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sync: true"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Synchronous — the API call blocks until migration completes or fails. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Timeout: 60 seconds."]}," If migration takes longer, the call returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["408 Request Timeout"]}," but migration continues in the background. Use for single-loan testing only."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sync: false"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Asynchronous — the API call returns immediately and migration runs in the background. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Recommended for production and bulk migrations."]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"monitor-migration-status","__idx":39},"children":["Monitor migration status"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For asynchronous migrations, poll the loan endpoint to check progress:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"GET /api/people/{personId}/loans/{loanId}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Watch the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," field:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Status"},"children":["Status"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Meaning"},"children":["Meaning"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Data preparation phase (pre-migrate call)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrating"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration in progress — Peach is replaying live events"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completed"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration completed successfully"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration failed — data has been rolled back"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"what-happens-during-migration","__idx":40},"children":["What happens during migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you call the migrate endpoint, Peach performs the following sequence:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Validates"]}," all migration data (periods, balances, transactions, draws)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Locks"]}," the loan to prevent concurrent modifications."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Originates"]}," the loan if it's in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]}," status."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Sets"]}," line-level grace period information from the migration period data."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Activates"]}," the LOC and updates draw information for the migration period."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Generates"]}," daily ledger management events."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Replays"]}," all live activities (purchases, transactions, fees) in chronological order."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Sets"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completed"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fires"]}," a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loan.migration.succeeded"]}," webhook event."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fires"]}," webhooks for all events created for live activities."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"if-migration-succeeds","__idx":41},"children":["If migration succeeds"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The loan status progresses from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originated"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["active"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," changes to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completed"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loan.migration.succeeded"]}," event is created and a webhook fires."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["All live activities are replayed and reflected in the loan's balance."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The loan begins accruing interest and generating billing events according to its configuration."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"if-migration-fails","__idx":42},"children":["If migration fails"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The system rolls back the ledger — no partial state is left."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The loan status reverts to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," changes to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loan.migration.failed"]}," event is created and a webhook fires."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["To retry after a failure:"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Review the error details in the migration event."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct the issue (fix data, adjust balances, etc.)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Reset ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]},":"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"PUT /api/people/{personId}/loans/{loanId}\nContent-Type: application/json\n\n{\n  \"migration\": {\n    \"migrationStatus\": \"prepMigration\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"ol","attributes":{"start":4},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Make any necessary data corrections."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Call the migrate endpoint again."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," If ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," shows ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]}," but you don't see specific errors, contact Peach Support for investigation."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-6-post-migration","__idx":43},"children":["Step 6: Post-migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After a successful migration, validate the results, adjust any discrepancies, and configure ongoing features."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"validate-balances","__idx":44},"children":["Validate balances"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Compare the following values between Peach and your legacy system:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Total outstanding balance (principal + interest + fees)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Due amounts (minimum payment due)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Overdue amounts and days past due"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Credit limit and available credit"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Individual draw balances"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Next payment due date and amount"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Interest rate(s) and any active promo rates"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Payment history accuracy"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Migrated payment instruments"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the following endpoints for validation:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"GET /api/people/{personId}/loans/{loanId}/balance\nGET /api/people/{personId}/loans/{loanId}/draws/{drawId}/balance\nGET /api/people/{personId}/loans/{loanId}/expected-payments\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"adjust-balances","__idx":45},"children":["Adjust balances"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If there's a discrepancy between Peach and your legacy system:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["If Peach balance is higher"]}," → apply a service credit:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/transactions\nContent-Type: application/json\n\n{\n  \"amount\": 5.43,\n  \"type\": \"serviceCredit\",\n  \"serviceCreditsDetails\": {\n    \"reason\": \"Migration balance adjustment\",\n    \"sponsor\": \"loanServicer\"\n  },\n  \"effectiveDate\": \"2024-08-01\",\n  \"effectiveTimeOfDay\": {\n    \"hour\": 12,\n    \"minute\": 0,\n    \"second\": 0\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["If Peach balance is lower"]}," → apply an adjustment fee or leave as-is (in the borrower's favor):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/fees\nContent-Type: application/json\n\n{\n  \"feeTypeId\": \"FT-ADJ-ABCD\",\n  \"amount\": 3.21,\n  \"chargeDate\": \"2024-08-01\",\n  \"chargeTimeOfDay\": {\n    \"hour\": 12,\n    \"minute\": 0,\n    \"second\": 0\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," The adjustment fee type (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["adHoc"]}," with a custom display name like \"Balance Adjustment\") must be configured by Peach. Contact your implementation team if you don't have one set up."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"configure-autopay","__idx":46},"children":["Configure autopay"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the borrower was enrolled in autopay on the legacy system, set it up in Peach ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["after"]}," migration completes."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/autopay\nContent-Type: application/json\n\n{\n  \"type\": \"lineOfCredit\",\n  \"paymentInstrumentId\": \"PI-1234-ABCD\",\n  \"autopayAmountLogic\": \"statement_minimum_amount\",\n  \"paymentScheduleDayOfMonth\": 22,\n  \"paymentFrequency\": \"monthly\",\n  \"consentDocumentId\": \"DD-CONSENT-ABCD\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Autopay timing:"]}," Configure autopay after the migrate call completes, not before. Peach does not process autopay payments during the migration replay period — if an autopay payment would have been due during the migration window, the system silently skips it. Be aware that it is possible to configure autopay schedules that don't align with your LOC billing frequency (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["twiceMonthly"]}," autopay on a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["monthly"]}," LOC), and there is currently no validation to prevent this, so ensure your autopay configuration matches your billing cycle."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"re-enable-borrower-communications-re-enable-borrower-communications","__idx":47},"children":["Re-enable borrower communications {#re-enable-borrower-communications}"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once you're confident the migration is successful and balances are correct, re-enable borrower notifications:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"PUT /api/people/{personId}/loans/{loanId}\nContent-Type: application/json\n\n{\n  \"muteLoanNotices\": false\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," Don't re-enable communications until you've completed balance validation and any necessary adjustments. Premature re-enablement can trigger confusing notifications to borrowers (e.g., payment reminders with incorrect amounts)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"set-up-credit-reporting","__idx":48},"children":["Set up credit reporting"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you report to credit bureaus, configure credit reporting during loan creation to maintain history continuity. You have two options."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For a full reference on Peach's credit reporting system, see the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/credit-reporting"},"children":["Metro 2® Credit Reporting Logic Guide"]},". The sections most relevant to migration are:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/credit-reporting/payment-rating-history"},"children":["Payment Rating and History"]}," — Payment History Profile character definitions and calculation algorithm (including migration history handling)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/credit-reporting/field-specifications"},"children":["Field Specifications"]}," — K2 Segment (Purchased From) and L1 Segment (Account Number Change) field details"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/credit-reporting/account-status"},"children":["Account Status Codes"]}," — How Peach determines status codes post-migration"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Option 1: Report with payment history"]}," (provide ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentHistoryProfile"]},")"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Include the borrower's Payment History Profile from the legacy system. This preserves up to 24 months of payment history on credit reports, ensuring no gap in the borrower's credit record."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pass the following fields in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.creditReporting"]}," object when creating the loan:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"migration\": {\n    \"migrationStatus\": \"prepMigration\",\n    \"activatedDate\": \"2023-06-15\",\n    \"activatedTimeOfDay\": { \"hour\": 10, \"minute\": 0, \"second\": 0 },\n    \"creditReporting\": {\n      \"paymentHistoryProfile\": \"000000000000000000000000\",\n      \"dateOfFirstDelinquency\": null,\n      \"k2Segment\": {\n        \"purchasedFromName\": \"LEGACY LENDER INC\"\n      },\n      \"l1Segment\": {\n        \"changeIndicator\": \"3\",\n        \"oldConsumerAccountNumber\": \"LEGACY-ACCT-12345\",\n        \"oldIdentificationNumber\": \"LEGACY-ID-6789\"\n      }\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentHistoryProfile"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["24-character string representing the last 24 months of payment history per the Metro 2 spec. Each character is a payment rating code. Most recent month first. See character definitions below."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dateOfFirstDelinquency"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["FCRA Date of First Delinquency (DOFD), if applicable. This value is provided as part of the migration process and is used directly by Peach the very first time the LOC is reported to credit bureaus. It does not interact with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedDaysOverdue"]}," — they are independent fields. Set to the date the account first became 30+ days past due on the legacy system. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," if the account has never been delinquent. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/credit-reporting/field-specifications#fcra-date-of-first-delinquency"},"children":["Field Specifications — FCRA Date of First Delinquency"]}," for how Peach uses this value post-migration."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["k2Segment.purchasedFromName"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Name of the entity the account was purchased or transferred from. Reported in the Metro 2 K2 Segment with a Purchased From indicator (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]},"). Maximum 30 characters, uppercase. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/credit-reporting/field-specifications#k2-segment-purchased-from--sold-to"},"children":["Field Specifications — K2 Segment"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["l1Segment.changeIndicator"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Indicates what changed during migration. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"1\""]}," = Consumer Account Number changed only. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"2\""]}," = Identification Number changed only. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"3\""]}," = both changed. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/credit-reporting/field-specifications#l1-segment-account-number-change"},"children":["Field Specifications — L1 Segment"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["l1Segment.oldConsumerAccountNumber"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The Consumer Account Number from the legacy system. Peach reports this old number in the Base Segment and the new Peach account number in the L1 Segment, so bureaus can link the records."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["l1Segment.oldIdentificationNumber"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The Identification Number (subscriber code) from the legacy system. Same reporting logic as the account number — old value in the Base Segment, new value in L1."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," The K2 and L1 segment fields are independent of the Payment History Profile. You can provide a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentHistoryProfile"]}," without K2/L1 segments, or vice versa, depending on your reporting needs."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Payment History Profile character definitions:"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentHistoryProfile"]}," string uses the standard Metro 2 character set. Use the codes from your legacy system's reporting data:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Character"},"children":["Character"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Meaning"},"children":["Meaning"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Current (0–29 days past due)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["30–59 days past due"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["60–89 days past due"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["3"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["90–119 days past due"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["4"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["120–149 days past due"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["5"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["150–179 days past due"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["6"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["180+ days past due"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["B"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No payment history available for this month"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["D"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No payment due (e.g., forbearance, bankruptcy)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["E"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Zero balance / current (open-ended accounts)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["L"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Charge-off"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For a complete reference on how Peach calculates the Payment History Profile post-migration (including how the migrated profile merges with live data), see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/credit-reporting/payment-rating-history"},"children":["Payment Rating and History"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentHistoryProfile"]}," string must be exactly 24 characters. If the account has fewer than 24 months of history, pad the remaining positions (oldest months) with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["B"]}," to indicate no prior history. For example, an account with 12 months of current history: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["000000000000BBBBBBBBBBBB"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Option 2: Report as new account"]}," (omit ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentHistoryProfile"]},")"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you don't have the borrower's Payment History Profile or prefer to start fresh, simply omit the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentHistoryProfile"]}," field from the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["creditReporting"]}," object:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"migration\": {\n    \"creditReporting\": {\n      \"dateOfFirstDelinquency\": null\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With this option, Peach reports the account without historical payment data. For months prior to the migration cutoff date, the Payment History Profile will show ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["B"]}," (no payment history available). History begins building from the migration date forward based on live loan performance."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Charge-off reason during migration:"]}," For accounts that were charged off on the legacy system, set the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["chargedOffReason"]}," value to match your legacy system's reason. Accepted values are ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["term"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fraudulent"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bankruptcy"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["legal"]},". Matching the reason ensures consistency between your legacy reporting and Peach's ongoing reporting."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"system-behavior-after-migration-succeeds","__idx":49},"children":["System behavior after migration succeeds"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," transitions to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completed"]},", several automated processes begin running on the migrated loan. Understanding this sequence helps you validate results and avoid surprises during the first billing cycle."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"when-daily-loan-maintenance-dlm-starts","__idx":50},"children":["When daily loan maintenance (DLM) starts"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Immediately after migration succeeds, Peach generates DLM events for the loan starting from the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["interest_start_date"]}," through today. DLM then runs daily (triggered by Google Cloud Scheduler at the start of US Pacific Time) for all subsequent days."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For migrated loans, DLM behavior depends on the loan's post-migration status:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Post-migration status"},"children":["Post-migration status"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"DLM runs?"},"children":["DLM runs?"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Interest accrues?"},"children":["Interest accrues?"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["active"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Yes"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["accelerated"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["chargedOff"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Tip:"]}," DLM is also responsible for balance movement between non-due, due, and overdue buckets, firing overdue/current events (used for webhooks), and charging late fees or service fees via a separate worker. For a deeper explanation of how DLM works for LOCs, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#appendix-a-loc-billing-cycle-mechanics"},"children":["Appendix A: LOC Billing Cycle Mechanics"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"first-post-migration-statement","__idx":51},"children":["First post-migration statement"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The statement for the migration previous period (the billing cycle immediately before the cutoff date) is generated ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["during the migrate call itself"]},", not at the next statement date. Peach populates the previous period's statement with draw balances from the ledger update events you provided in the migration period data. This statement is used for autopay generation."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The first ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["new"]}," statement generates at the next ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]}," boundary after migration. For example, if your migration period runs Aug 1–Aug 31 with a statement date of Sep 1, the first new statement generates on Sep 1."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"snapshot-backfill","__idx":52},"children":["Snapshot backfill"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After migration completes, Peach queues a snapshot backfill that regenerates balance snapshots for every day between the migration cutoff date and the current date. This ensures that balance history is continuous for reporting and loan tape purposes."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," The snapshot backfill process is being improved for greater reliability. Note that you should not see interest accrual on the migration cutoff date + 1 day — the backfill preserves historical consistency by not introducing interest charges for the cutoff boundary day."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"how-ongoing-activity-works","__idx":53},"children":["How ongoing activity works"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After migration, the way you create activity changes:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Activity"},"children":["Activity"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"During migration"},"children":["During migration"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"After migration"},"children":["After migration"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purchases"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Posted to migration draw with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originalDrawId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Posted to actual draws (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /draws/{drawId}/purchases"]},")"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Transactions"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../transactions"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isExternal: true"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../transactions"]}," (standard — no ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isExternal"]}," flag)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fees"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../fees"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration.originalDrawId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../fees"]}," (standard)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Payment instruments"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isExternal: true"]}," for historical instruments"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Standard instruments"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," After migration, the migration draw (drawType=Static) is disabled. Do not attempt to post new activity to it — the API will reject requests targeting a static draw with the error \"This endpoint is invalid for a static draw.\""]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"what-happens-at-the-next-billing-cycle-boundary","__idx":54},"children":["What happens at the next billing cycle boundary"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The first post-migration billing cycle follows the standard LOC balance movement timeline:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["On statement date"]},": Non-due balances move to due. The amount moved equals the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["remainingAmount"]}," from the obligation for that period. Interest is truncated at this step — any fractional cents are moved to a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["forgone_interest_rounding"]}," bucket. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#appendix-a-loc-billing-cycle-mechanics"},"children":["Appendix A: LOC Billing Cycle Mechanics"]}," for details."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Between statement date and due date"]},": Balances sit in \"due\" buckets for 2–3 weeks. Borrowers make payments during this window. For LOC products with grace periods, payments applied during this window may have their ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effectiveDate"]}," set to the statement date for interest calculation purposes. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#appendix-b-grace-period-for-lines-of-credit"},"children":["Appendix B: Grace Period for Lines of Credit"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["On due date + 1"]},": Any remaining due balance moves to overdue. The system fires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loan_overdue"]}," events, checks grace period eligibility, and evaluates whether the loan qualifies for acceleration or charge-off based on the loan type's overdue day threshold."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"what-you-can-and-cant-change-after-migration-what-you-can-and-cant-change-after-migration","__idx":55},"children":["What you can and can't change after migration {#what-you-can-and-cant-change-after-migration}"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After migration succeeds, you may need to correct data or handle borrower disputes. Peach supports a specific set of post-migration modifications, with constraints that reflect the migration draw's read-only nature and the system's data integrity rules."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"supported-modifications","__idx":56},"children":["Supported modifications"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Action"},"children":["Action"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"How"},"children":["How"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Notes"},"children":["Notes"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Dispute a historical purchase"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../draws/{drawId}/purchases/{purchaseId}/disputes"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Creates a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: \"refund\""]}," purchase with an effective date after the cutoff. Lowers draw balance using standard refund functionality."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Waive or cancel a historical fee"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT .../fees/{feeId}/cancel"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Changes fee status to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["canceled"]}," and depletes the fee balance. If fee balance is already zero, depletes draw principal instead."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Change a past transaction's status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT .../migration/past-transaction/{txnId}"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Allowed transitions: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["succeeded"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]},"/",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["succeeded"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},". For transitions to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},", the system uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," from the original transaction to increase draw balances."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Reverse a historical transaction"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../transactions/{txnId}/reverse"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Creates a reversal transaction. For each entry in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]},", increases the corresponding draw's non-due principal balance."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Correct and re-create with same external ID"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Clear the external ID on the original object, then create a new one"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["For purchases: update with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["externalId: null"]},". For transactions: cancel with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["clearExternalId: true"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Apply balance adjustments"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Service credits (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../transactions"]},") or adjustment fees (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../fees"]},")"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Use for post-validation balance discrepancies. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#adjust-balances"},"children":["Adjust balances"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"constraints-on-modifications","__idx":57},"children":["Constraints on modifications"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["These constraints exist because of how the migration draw and historical data are stored:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Migration draw is disabled after migration."]}," You cannot post new purchases, transactions, or fees to the static draw. All new activity must target actual draws."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," required for past-transaction status changes to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},"."]}," When marking a past transaction as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},", the system needs to know which draws to increase balances for. If ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," is null (which can happen for transactions that pre-date the migration cutoff), the status change to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]}," will be rejected."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," only available via migration endpoint."]}," Past-transaction ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," are returned by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../migration/past-transaction"]},", ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," by the standard ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../transactions"]}," endpoint. If you need draw allocation details for a historical transaction, always use the migration-specific endpoint."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Past periods are read-only."]}," Statement-cycle snapshots created via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../migration/past-periods"]}," cannot be modified after migration succeeds. If you need to correct a past period, you would need to cancel and re-migrate the loan."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cannot reverse acceleration or charge-off for loans migrated with a non-null ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["postMigrationLoanStatus"]},"."]}," If a loan was created with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["postMigrationLoanStatus: \"accelerated\""]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["postMigrationLoanStatus: \"chargedOff\""]}," (meaning it was in that state before the cutoff date), the system blocks reverse-acceleration and reverse-charge-off operations. Loans that are accelerated or charged off ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["after"]}," migration (through normal DLM processing) can be reversed normally."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cannot add new past periods after migration."]}," The past-periods endpoints are only available while the loan is in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]}," status."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"what-the-system-wont-let-you-do","__idx":58},"children":["What the system won't let you do"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Action"},"children":["Action"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Why"},"children":["Why"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Post new activity to the migration draw"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Static draws are disabled after migration"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Modify past period data"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Past periods are read-only snapshots"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Change ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," back to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration status can only move forward in the lifecycle"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Reverse accel/charge-off for loans created with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["postMigrationLoanStatus"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["These status changes preceded the migration cutoff; the system considers them historical"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Mark a past transaction as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]}," without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The system needs draw allocation data to reverse the transaction's balance impact"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"system-design-constraints-and-known-behaviors","__idx":59},"children":["System design constraints and known behaviors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["These behaviors are by design but may surprise clients who expect the system to work differently than their legacy platform."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"grace-period-override-during-migration","__idx":60},"children":["Grace period override during migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a draw is configured with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]}," greater than 1 (meaning the borrower must pay in full for multiple consecutive periods to regain grace), this rule is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["overridden to 1"]}," during the migration period. Peach defaults to the borrower-favorable behavior because it does not have per-draw grace history for pre-migration periods. The configured ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]}," takes full effect starting in the period after migration. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#appendix-b-grace-period-for-lines-of-credit"},"children":["Appendix B: Grace Period for Lines of Credit"]}," for details."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"dpd-calculation-for-migrated-loans","__idx":61},"children":["DPD calculation for migrated loans"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Days past due for migrated loans combines the migrated overdue days with the time elapsed since cutoff:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"effectiveDPD = peachTimeDiff + maxMigratedDaysOverdue\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Where ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["peachTimeDiff"]}," is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(today - migrationCutoffDate).days"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["maxMigratedDaysOverdue"]}," is the highest ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedDaysOverdue"]}," value across all obligations. This means DPD continues to increase after migration if the borrower doesn't pay — it doesn't reset to zero at cutoff."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["As the borrower pays down the overdue balance, the migrated overdue remaining amount decreases:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"migratedOverdueRemainingAmount = migratedOverdueAmount - amountPaid\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedOverdueRemainingAmount"]}," reaches zero, the migrated overdue component is fully resolved."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," The DPD prorating is continuous and does not account for period-level overdue buckets. This can produce unexpected results when a borrower has overdue balances spanning multiple periods. For example, if a borrower has overdue balances of $100 from period 1 (90 days overdue), $100 from period 2 (60 days overdue), and $800 from period 3 (30 days overdue), and they pay $200, they might expect to be considered only 30 days overdue (having cleared the two oldest periods). However, the system pro-rates continuously: with 80% of the total overdue amount remaining, it calculates 80% × 90 = 72 days overdue. This behavior is on the roadmap to be improved, but it is the current system behavior."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"no-loan-tapes-for-pre-migration-periods","__idx":62},"children":["No loan tapes for pre-migration periods"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Peach does not generate loan tapes for periods before the migration cutoff date. After migration, loan tape fields are conditionally enabled based on whether the loan has a migration cutoff. This means historical loan tape data from before the cutoff must be sourced from your legacy system."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"past-transaction-drawsplitdetails-access","__idx":63},"children":["Past-transaction drawSplitDetails access"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," field for past transactions (showing how a payment was allocated across draws) is only available through the migration-specific endpoint (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../migration/past-transaction"]},"). The standard ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../transactions"]}," endpoint does not return this field. This is a common source of confusion when building post-migration reconciliation tools."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"balance-precision-and-credit-balance-handling","__idx":64},"children":["Balance precision and credit balance handling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["All balance amounts must have a precision of exactly 0.01 (two decimal places) and be ≥ 0.00. Amounts with more than two decimal places are rejected. If a borrower has a credit balance (the lender owes the borrower money), use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["reimbursementAmount"]}," field — do not use negative principal values."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"statement-date-must-be-enddate--1","__idx":65},"children":["Statement date must be endDate + 1"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Peach enforces a hard constraint: the statement date must be exactly one day after the period's end date. If ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate != endDate + 1 day"]},", validation fails. This is worth noting because some legacy systems use different date conventions."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"effective-time-of-day-minimum","__idx":66},"children":["Effective time of day minimum"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["All transactions must have an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effectiveTimeOfDay"]}," after 2:00 AM in the product's timezone. Transactions with earlier times fail validation. This constraint exists because DLM processes run in the early morning hours, and transactions must not conflict with those processes."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"overdue-amount-and-days-overdue-consistency","__idx":67},"children":["Overdue amount and days overdue consistency"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The system validates that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedDaysOverdue"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedOverdueAmount"]}," are consistent:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Cannot have ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedDaysOverdue > 0"]}," if ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedOverdueAmount"]}," is 0"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Cannot have ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedOverdueAmount > 0"]}," if ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedDaysOverdue"]}," is 0"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Cannot have ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedOverdueAmount > 0"]}," if the total ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["obligationAmount"]}," is less than the statement's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["minimumAmountDue"]}," (this implies payments were made that should have reduced the overdue state)"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"interest-rounding-for-locs","__idx":68},"children":["Interest rounding for LOCs"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["At statement date, when non-due interest moves to due, the system truncates to the nearest cent. The fractional cents are moved to a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["forgone_interest_rounding"]}," bucket and are not recovered. Over many periods, this can create small discrepancies between Peach's interest calculation and a legacy system that rounds differently."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"origination-and-draw-fees","__idx":69},"children":["Origination and draw fees"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the LOC charges origination fees or draw fees that are expected to be paid after the migration cutoff date, configure them during loan and draw creation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"origination-fees","__idx":70},"children":["Origination fees"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pass the origination fee amount in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["atOrigination.fees"]}," object when creating the loan:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"atOrigination\": {\n    \"fees\": {\n      \"originationFeeAmount\": 150.00\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Then include the remaining origination fee balance in the migration period LOC data under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nonDueBalances.nonDueOriginationFeesAmount"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueBalances.dueOriginationFeesAmount"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overdueBalances.overdueOriginationFeesAmount"]}," depending on the fee's current status."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"draw-fees","__idx":71},"children":["Draw fees"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pass the draw fee amount in the draw's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["atOrigination.fees"]}," object:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"atOrigination\": {\n    \"fees\": {\n      \"drawFeeAmount\": 50.00\n    }\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Include the remaining draw fee balance in the migration period draw data under the appropriate ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nonDueDrawFeesAmount"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDrawFeesAmount"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overdueDrawFeesAmount"]}," field."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"statement-and-due-date-configuration","__idx":72},"children":["Statement and due date configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Peach supports three options for statement and due date scheduling on LOCs. The option you choose affects how you set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specificDays"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}," across all periods."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Option"},"children":["Option"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"How it works"},"children":["How it works"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Configuration"},"children":["Configuration"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fixed due date"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Due date is fixed; statement date is calculated based on grace period days."]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specificDays"]}," to the due date day (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[22]"]},"). Statement date is auto-calculated."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fixed statement date"]}," (LOC only)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Statement date is fixed; due date is calculated based on grace period days."]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specificDays"]}," to the statement date day. Due date is auto-calculated."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Fixed both"]}," (LOC only, monthly only)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Both statement date and due date are fixed."]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specificDays"]}," to both days (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[1, 22]"]}," where 1 is statement date, 22 is due date). Only works with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentFrequency: \"monthly\""]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Ensure that the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specificDays"]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["atOrigination"]}," align with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}," (or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]},", depending on your configuration) in the migration period data."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"modifying-historical-data-post-migration","__idx":73},"children":["Modifying historical data post-migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For a complete reference on what you can and can't change after migration — including supported modifications, constraints, and code examples — see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#what-you-can-and-cant-change-after-migration"},"children":["What you can and can't change after migration"]}," in Step 6."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following are the API code examples for each supported modification type."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"dispute-historical-purchases","__idx":74},"children":["Dispute historical purchases"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a borrower disputes a purchase that occurred before the migration cutoff date:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/draws/{drawId}/purchases/{purchaseId}/disputes\nContent-Type: application/json\n\n{\n  \"reason\": \"unauthorized\",\n  \"amount\": 249.99\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This creates a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: \"refund\""]}," purchase with an effective date after the migration cutoff, which lowers the draw balance using the existing refund functionality."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"waive-or-cancel-historical-fees","__idx":75},"children":["Waive or cancel historical fees"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cancel a fee that was charged before the migration cutoff date:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"PUT /api/people/{personId}/loans/{loanId}/fees/{feeId}/cancel\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The system changes the fee status to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["canceled"]}," and depletes the fee balance. If the fee balance is already zero, it depletes draw principal instead."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"change-historical-transaction-status","__idx":76},"children":["Change historical transaction status"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Update the status of a past transaction (e.g., marking a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]}," payment as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["succeeded"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},"):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"PUT /api/people/{personId}/loans/{loanId}/migration/past-transaction/{transactionId}\nContent-Type: application/json\n\n{\n  \"status\": \"failed\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Allowed transitions: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["succeeded"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]},"/",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["succeeded"]}," → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," For transitions to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},", the system requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," from the original transaction to know which draw balances to increase. These details are only available via the migration-specific endpoint (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET .../migration/past-transaction"]},"), not the standard transactions endpoint. If ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]}," is null, the status change to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]}," will be rejected."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"reverse-historical-transactions","__idx":77},"children":["Reverse historical transactions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Reverse a past transaction to undo its effect:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/transactions/{transactionId}/reverse\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The system creates a new reversal transaction. For each entry in the original ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawSplitDetails"]},", the system increases the corresponding draw's non-due principal balance."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"correct-and-re-create-purchases-or-transactions","__idx":78},"children":["Correct and re-create purchases or transactions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you need to delete and re-create a purchase or transaction with the same external ID:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purchases:"]}," Update the purchase with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["externalId: null"]}," to release the external ID, then create a new purchase with the original external ID."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Transactions:"]}," Cancel the transaction with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["clearExternalId: true"]}," to release the external ID, then create a new transaction with the original external ID."]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"migrating-special-loan-states","__idx":79},"children":["Migrating special loan states"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Not all loans are current when they migrate. Peach supports migrating loans that are delinquent, accelerated, or charged off."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"delinquent-loans","__idx":80},"children":["Delinquent loans"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For loans that are past due at the time of migration, set the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedDaysOverdue"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedOverdueFromDate"]}," fields in the migration period obligation data."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After migration, Peach dynamically prorates the migrated days overdue as the borrower makes payments:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Effective DPD = migratedDaysOverdue × (1 - min(fulfilledAmount / migratedOverdueAmount, 1))\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This means that as the borrower pays down the overdue balance, the effective days past due decreases proportionally."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," This prorating formula operates continuously across the total overdue amount and does not distinguish between overdue amounts from different periods. See the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#dpd-calculation-for-migrated-loans"},"children":["DPD prorating known limitation"]}," in the system design constraints section for a detailed example of how this can produce unexpected results with multi-period overdue balances."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"accelerated-and-charged-off-loans","__idx":81},"children":["Accelerated and charged-off loans"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To migrate a loan directly into an accelerated or charged-off state, set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["postMigrationLoanStatus"]}," in the migration period LOC data:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"postMigrationLoanStatus\": \"accelerated\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Or for charged-off:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"postMigrationLoanStatus\": \"chargedOff\",\n  \"chargedOffReason\": \"term\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Accepted ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["chargedOffReason"]}," values:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["term"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fraudulent"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bankruptcy"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["legal"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The effective date for the acceleration or charge-off is the migration cutoff date."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Special state migrations"]}," are most commonly used when onboarding a portfolio of delinquent loans onto Peach — for example, to leverage Peach's collections features for a portfolio where all loans are already past due. Ensure the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["chargedOffReason"]}," matches the reason from your legacy system."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"migration-strategy-and-operations","__idx":82},"children":["Migration strategy and operations"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For large portfolio migrations, follow these operational best practices."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"batching-and-segmentation","__idx":83},"children":["Batching and segmentation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If migrating a large portfolio, segment it into batches. Start small and increase batch size as you gain confidence:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Start with 50 loans"]}," — validate thoroughly"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Increase to 100, then 250, then 500"]}," — monitor for patterns"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Scale to your target batch size"]}," once the process is stable"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Group loans with similar attributes in each batch:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Current loans together"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Delinquent loans together"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Loans with promo programs together"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Loans with specific fee configurations together"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This makes it easier to identify reconciliation patterns. For example, if all loans in a \"delinquent\" batch show a consistent DPD offset, you can diagnose the root cause once and apply the fix to the entire batch."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["There is no hard limit on batch size in production, but we recommend monitoring migration completion times and adjusting batch sizes based on your throughput requirements."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"borrower-communications-during-migration","__idx":84},"children":["Borrower communications during migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["muteLoanNotices: true"]}," on loan creation to prevent notifications during migration. This avoids confusing borrowers with messages like payment reminders or balance alerts while data is still being set up."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Re-enable communications only after:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Migration has succeeded"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Balances have been validated"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Autopay has been configured (if applicable)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You're ready to sunset the legacy system's communications for that borrower"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"concurrent-system-operation","__idx":85},"children":["Concurrent system operation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During migration, both your legacy system and Peach can operate simultaneously. This allows for thorough testing and validation without disrupting your business."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"canceling-and-re-migrating-loans","__idx":86},"children":["Canceling and re-migrating loans"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a loan was migrated incorrectly and cannot be fixed with adjustments, you can cancel it and re-migrate. This is also the recovery path if you miss the migration period due date — the loan must be canceled and re-created with a new migration period aligned to your next statement date."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Option A — Clear all external IDs automatically"]}," (up to 1,000 objects):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"POST /api/people/{personId}/loans/{loanId}/cancel?clearAllExternalIds=true\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This clears external IDs on the loan, all its draws (including the migration draw, which is auto-canceled), transactions, purchases, and fees — up to 1,000 objects total. If your loan has more than 1,000 associated objects, use Option B."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Option B — Manual cleanup for large loans"]}," (> 1,000 objects):"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Cancel each draw individually, clearing its external IDs."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Cancel the loan with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["clearAllExternalIds=true"]}," for the remaining objects."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After cancellation:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Create a new loan"]}," with the original external ID and repeat the migration process."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If you need to adjust data on the canceled loan before re-migrating (e.g., convert migration period data to a past period, reclassify live activities as past activities), you can update the canceled loan's data first."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Info:"]}," Canceled loans do not appear on loan tapes. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["clearAllExternalIds"]}," parameter frees up external IDs for re-use on the corrected loan without requiring manual changes."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"validation-rules-and-common-errors","__idx":87},"children":["Validation rules and common errors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Peach validates migration data at multiple points. Understanding these rules helps prevent failures."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"period-validation","__idx":88},"children":["Period validation"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Rule"},"children":["Rule"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Error symptom"},"children":["Error symptom"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No gaps between periods"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startDate"]}," of period N+1 must equal ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate"]}," of period N + 1 day"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No overlapping start-end date ranges"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startDate"]},"–",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate"]}," range of one period cannot overlap with another period's range"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No duplicate dates"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Two periods cannot share the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startDate"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Due date falls in next period"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Each period's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}," must fall between the next period's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startDate"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"transaction-validation","__idx":89},"children":["Transaction validation"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Rule"},"children":["Rule"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Error symptom"},"children":["Error symptom"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effectiveTimeOfDay"]}," must be after 2:00 AM"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Transactions with earlier times fail validation"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["External transactions require ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isExternal: true"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Live transactions processed by legacy system must be flagged as external"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Historical transactions use the past-transaction endpoint"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Don't use the standard transaction endpoint for pre-cutoff activity"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"balance-validation","__idx":90},"children":["Balance validation"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Rule"},"children":["Rule"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Error symptom"},"children":["Error symptom"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["All amounts ≥ 0.00"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Negative amounts are rejected"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Precision of 0.01"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Amounts with more than 2 decimal places are rejected"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Credit balances use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["reimbursementAmount"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Don't use negative principal for credit balances"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Overdue balances must match obligations"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["If the obligation states the borrower is overdue by a certain amount, the overdue balance amounts across draws must add up to that amount. Mismatches will cause migration to fail."]}]}]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"troubleshooting-and-faq","__idx":91},"children":["Troubleshooting and FAQ"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"balance-discrepancies","__idx":92},"children":["Balance discrepancies"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: Why doesn't my balance match the legacy system?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Balance discrepancies after migration almost always trace back to one of the following root causes. Work through this diagnostic sequence:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 1 — Compare total balance first."]}," If the total outstanding balance (principal + interest + fees) matches but the breakdown doesn't, skip to \"Principal/interest split differences\" below. If the total doesn't match, continue."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 2 — Check balance timing."]}," Balances must be provided as of the migration cutoff date. The codebase enforces a specific rule: balances should include interest accrued through the last day of the previous period (endDate) but should NOT include interest for the statement date (migration period start date). If you included an extra day of interest, you'll see a small positive discrepancy."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 3 — Check day count conventions."]}," Peach accrues interest for the actual number of days in each month. Some legacy systems use a 30-day month convention (30/360). This means:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Month"},"children":["Month"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Peach (actual days)"},"children":["Peach (actual days)"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"30/360 system"},"children":["30/360 system"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Difference per $10,000 at 18% APR"},"children":["Difference per $10,000 at 18% APR"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["February (non-leap)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["28 days"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["30 days"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["-$0.99"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["February (leap)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["29 days"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["30 days"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["-$0.49"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["March"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["31 days"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["30 days"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["+$0.49"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Over a full year these differences partially cancel out, but at any given cutoff date there may be a discrepancy of a few dollars."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 4 — Check rounding behavior."]}," Peach accrues interest daily with high precision, then truncates to the nearest cent at statement date. Fractional cents go to a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["forgone_interest_rounding"]}," bucket. If your legacy system rounds at a different cadence (e.g., per-period rather than per-day), small cumulative rounding differences are expected."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 5 — Break down by draw."]}," Compare balances at the draw level. If one specific draw is off, check that draw's interest rate, promo rate, and fee configuration. A mismatched rate will compound over the post-cutoff period."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Minor discrepancies (typically < $1.00) are normal and can be addressed with service credits or adjustment fees. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#adjust-balances"},"children":["Step 6: Post-migration → Adjust balances"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"principalinterest-split-differences","__idx":93},"children":["Principal/interest split differences"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: Why is the principal/interest split different from my legacy system?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Peach replays live activity chronologically and applies its own interest calculation rules. Common causes of split differences:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Accrual method"]},": Peach uses daily accrual with actual/365 day counting. If your legacy system uses 30/360 or periodic (monthly) accrual, the interest component will differ."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Interest truncation at statement date"]},": For LOCs, when non-due interest moves to due at statement date, the system truncates to the nearest cent. The fractional amount goes to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["forgone_interest_rounding"]},". If your legacy system doesn't truncate at this step, interest will accumulate differently."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Grace period retroactive accrual"]},": If a borrower is in grace and makes a payment between statement date and due date, Peach backdates the payment's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effectiveDate"]}," to the statement date for interest calculation purposes. If your legacy system applies the payment at the actual date, the interest calculation will differ for that period."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The total balance should still match within tolerance — if it doesn't, check the balance timing and day count rules above."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"interest-calculation-after-grace-period-revocation","__idx":94},"children":["Interest calculation after grace period revocation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: Why did the borrower get a large interest charge after migration?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the borrower was in grace before migration but the grace period was revoked post-migration (because they didn't pay in full by the due date), Peach accrues interest retroactively on the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["unpaid portion"]}," from the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["statement date"]},", not from the due date. This is by design (see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#appendix-b-grace-period-for-lines-of-credit"},"children":["Appendix B: Grace Period for Lines of Credit"]},") but can produce a larger interest charge than expected if the borrower had been in grace for a long period."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Check: Was ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isGracePeriodEligible"]}," set correctly in the migration period data? If it was set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," but the borrower shouldn't have been in grace, the system will have suppressed interest accrual during the migration period and then retroactively accrued when grace was revoked — creating a sudden lump-sum charge."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"loan-tapes-after-migration","__idx":95},"children":["Loan tapes after migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: How do migrated loans appear on loan tapes?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Peach does not generate loan tapes for periods before migration. After migration, the system generates loan tapes based on your tape configuration. Migrated loans appear on tapes as if they are any other loan. Canceled loans do not appear on loan tapes. Loan tape fields are conditionally enabled based on whether the loan has a migration cutoff — some fields that depend on full loan history may not be available for migrated loans."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"migration-processing-time","__idx":96},"children":["Migration processing time"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: How long does migration take?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Processing time depends on the number of draws, historical activities (purchases, transactions, fees), and batch size."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Mode"},"children":["Mode"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Behavior"},"children":["Behavior"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Recommended for"},"children":["Recommended for"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Synchronous"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sync=true"]},")"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Blocks until migration completes or 60-second timeout"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Single loans, testing"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Asynchronous"]}," (default)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Returns immediately, processes in background"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Production, batches"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If sync mode times out (HTTP 408), the migration is still processing — check ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus"]}," via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /loans/{loanId}"]},". A single loan with a few draws and modest history typically migrates in seconds. Loans with many draws and extensive transaction history may take minutes."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For large batches, always use async mode. Monitor progress by polling loan status or subscribing to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loan.migration.succeeded"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loan.migration.failed"]}," webhook events."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"failed-migration-with-no-errors","__idx":97},"children":["Failed migration with no errors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: Migration status shows ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]}," but I don't see specific errors. What do I do?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Contact Peach Support. Some failure scenarios (e.g., internal timeouts during replay) don't surface user-facing errors. Support can investigate the migration event logs."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When migration fails, the system automatically:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Rolls back the loan status to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Clears the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrated_at"]}," timestamp"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Reverses all ledger entries created during the migration attempt"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Resets the migration status to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can then reset to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["prepMigration"]},", correct any data issues, and attempt migration again."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"re-using-external-ids-after-cancellation","__idx":98},"children":["Re-using external IDs after cancellation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: I canceled a migrated loan but can't create a new loan with the same external ID."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["External IDs must be unique across all loans in your company, including canceled ones. Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["clearAllExternalIds=true"]}," when canceling (see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#canceling-and-re-migrating-loans"},"children":["Canceling and re-migrating loans"]},"), or change the external ID on the incorrectly migrated loan before canceling (e.g., append ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-canceled"]},")."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"sandbox-testing","__idx":99},"children":["Sandbox testing"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: Can I test the full migration workflow in sandbox?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Yes. Sandbox supports the complete migration workflow. Limit testing to 5 loans at a time — larger batches may cause processing delays or aborted migrations."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"migration-validation-errors","__idx":100},"children":["Migration validation errors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: What does \"Loan is missing ledger update event\" mean?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /migrate"]}," endpoint validates that every non-static draw has a corresponding ledger update event (created when you set up the migration period data). This error means you created a draw but didn't create migration period data for it. Create the migration period draw data (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST .../draws/{drawId}/migration/period"]},") for the missing draw, then retry migration."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Q: What does \"Operation would lead to periods overlapping\" mean?"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The period validation checks that no two periods have overlapping start-end date ranges, that there are no gaps between consecutive periods, and that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate = endDate + 1 day"]},". Review your past periods data and migration period data for date inconsistencies. Common causes: daylight saving time boundaries, months with different day counts, or off-by-one errors in date calculations."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"webhook-events","__idx":101},"children":["Webhook events"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Peach does not fire webhooks during the migration process itself. After migration completes successfully, webhooks begin firing for subsequent loan activity."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Event"},"children":["Event"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"When it fires"},"children":["When it fires"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loan.migration.succeeded"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration completed successfully"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loan.migration.failed"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration failed and was rolled back"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Events for live activities"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["After successful migration, webhooks fire for all events created during replay of live activities"]}]}]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"api-quick-reference","__idx":102},"children":["API quick reference"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Action"},"children":["Action"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Method"},"children":["Method"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Endpoint"},"children":["Endpoint"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create borrower"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create contact"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/contacts"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create payment instrument"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/payment-instruments"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create loan (LOC)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["List draws"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/draws"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create draw"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/draws"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create document"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/documents"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Upload document content"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/documents/{docId}/content"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create past periods"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/past-periods"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Get past periods"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/past-periods"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Update past period"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/past-periods"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Delete past period"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DELETE"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/past-periods"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create migration period (LOC)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/period"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Get migration period (LOC)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/period"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Update migration period (LOC)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/period"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create migration period (draw)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/draws/{drawId}/migration/period"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Get migration period (draw)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/draws/{drawId}/migration/period"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Update migration period (draw)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/draws/{drawId}/migration/period"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Update loan status"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create purchase"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/draws/{drawId}/purchases"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create past transaction"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/past-transaction"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Get past transactions"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/past-transaction"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Update past transaction"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migration/past-transaction/{txnId}"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create transaction"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/transactions"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create fee"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/fees"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migrate loan"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/migrate"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Get loan (check status)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Get balance"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/balance"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create autopay"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/autopay"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Cancel fee"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/fees/{feeId}/cancel"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Reverse transaction"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/transactions/{txnId}/reverse"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Create purchase dispute"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/draws/{drawId}/purchases/{purchaseId}/disputes"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Cancel loan"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/people/{personId}/loans/{loanId}/cancel"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"appendix-a-loc-billing-cycle-mechanics-appendix-a-loc-billing-cycle-mechanics","__idx":103},"children":["Appendix A: LOC Billing Cycle Mechanics {#appendix-a-loc-billing-cycle-mechanics}"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A line of credit billing cycle is fundamentally different from an installment loan. Understanding this structure is critical for migration because Peach must initialize balance buckets correctly at cutover — and post-migration, these mechanics govern how balances move, when interest accrues, and when a borrower becomes overdue."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"billing-period-structure","__idx":104},"children":["Billing period structure"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every LOC billing cycle is divided into periods defined by four key dates:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Date"},"children":["Date"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"What happens"},"children":["What happens"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["startDate"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Period begins. New balance tracking starts."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["endDate"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Period ends. Last day of the billing period."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["statementDate"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Statement generated. Always ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate + 1"]},". Non-due balances move to due."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["dueDate"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Payment deadline. Full balance must be paid by this date for grace (if applicable)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["dueDate + 1"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Enforcement. Unpaid due amounts move to overdue. Grace eligibility checked."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," In Peach, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]}," must always equal ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate + 1 day"]},". This is a hard validation rule — if they don't match, migration will fail with \"Period statement date should be one day after end date.\""]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"balance-movement-non-due--due--overdue","__idx":105},"children":["Balance movement: non-due → due → overdue"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Unlike installment loans where a single payment obligation comes due on one date, LOCs move balances through buckets on specific dates."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"non-due-to-due-statement-date","__idx":106},"children":["Non-due to due (statement date)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Between ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["startDate"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]},", all accrued interest and posted transactions sit in the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["non-due"]}," bucket. On ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]},", the system moves the remaining non-due balance to the due bucket. The amount moved equals the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["remainingAmount"]}," from the obligation for that period."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During this step, outstanding non-due interest is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["truncated"]}," to the nearest cent. Any fractional cents are moved to a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["forgone_interest_rounding"]}," bucket and are not recovered. This is a key difference from systems that round interest at a different cadence."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"due-to-overdue-due-date--1","__idx":107},"children":["Due to overdue (due date + 1)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]},", the balance sits in the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["due"]}," bucket. For LOCs, this is typically 2–3 weeks (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate - statementDate + 1"]}," days). On ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate + 1"]},", any remaining due balance moves to overdue."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Loan type"},"children":["Loan type"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Non-due → due"},"children":["Non-due → due"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Time in \"due\""},"children":["Time in \"due\""]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Due → overdue"},"children":["Due → overdue"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Line of credit"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Statement date"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["2–3 weeks"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Due date + 1"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Installment"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Due date"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["1 day"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Due date + 1"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is the most important structural difference between LOCs and installment loans. For installment loans, balances move from non-due to due on the due date and become overdue just one day later. For LOCs, there's a substantial window between \"due\" and \"overdue.\""]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"obligations-tracking-what-the-borrower-owes","__idx":108},"children":["Obligations: tracking what the borrower owes"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["An ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["obligation"]}," tracks how much the borrower must pay in a specific billing period. It answers: \"How much is owed, how much has been paid, and how much remains?\""]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The obligation amount is computed from ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["expected payments"]}," — forecasts of what the borrower should pay based on the loan's schedule and fee structure:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"obligationAmount = sum(expectedPayment.amount)\n  where expectedPayment.period_id = obligation.period_id\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Expected payments include: one ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PeriodicPayment"]}," (principal + interest), any number of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DynamicFee"]}," entries (e.g., periodic servicing fees), and optionally one ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OriginationFee"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DrawFee"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The obligation also tracks payment progress:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"fulfilledAmount = paymentsAmount + serviceCreditsAmount\nremainingAmount = obligationAmount - fulfilledAmount\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fulfilledAmount"]}," calculation respects the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["allowPrepayments"]}," loan type setting. If prepayments are allowed, a borrower's early payment can satisfy future obligations. If prepayments are not allowed, excess payments are tracked as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overpaymentsAmount"]}," but don't reduce future ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["remainingAmount"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["refresh_obligations()"]}," function recomputes all obligations whenever a relevant event occurs (payment, service credit, refund, etc.)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-this-matters-for-migration","__idx":109},"children":["Why this matters for migration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During migration, you must seed Peach's ledger with the correct balance buckets. Your legacy system's balances must be broken down into non-due, due, and overdue — ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["per fee type"]}," (principal, interest, periodic fees, late fees, origination fees, draw fees, etc.). If these breakdowns are incorrect, post-migration DLM will move the wrong amounts at statement date, causing balance discrepancies."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You also need to provide the correct ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["obligationAmount"]}," for the migration period (reconstructed from your legacy system's billing data). For overdue loans, you must include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedDaysOverdue"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migratedOverdueAmount"]}," so that Peach can correctly track the borrower's delinquency status going forward."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"timeline-example","__idx":110},"children":["Timeline example"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Day 1 (Aug 1):    startDate — Period begins\n                   ├─ Interest accrues daily in non-due bucket\n                   ├─ Purchases post to non-due bucket\n                   └─ Borrower can make payments (reduce non-due)\n\nDay 31 (Aug 31):  endDate — Period ends\n\nDay 32 (Sep 1):   statementDate — Statement generated\n                   ├─ Non-due balance moves to due bucket\n                   ├─ Interest truncated (fractional cents → forgone_interest_rounding)\n                   ├─ Obligation sealed (obligationAmount set)\n                   └─ Statement mailed/emailed to borrower\n\nDays 32–53:       Due period (balance in \"due\" for ~3 weeks)\n                   ├─ Borrower makes payments (reduce due)\n                   └─ Grace: payments effectiveDate → statementDate if eligible\n\nDay 53 (Sep 22):  dueDate — Payment deadline\n                   └─ Last day to pay for grace eligibility\n\nDay 54 (Sep 23):  dueDate + 1 — Enforcement\n                   ├─ Remaining due balance moves to overdue\n                   ├─ Grace eligibility checked (revoke or reinstate)\n                   ├─ loan_overdue event fires (if overdue)\n                   ├─ Late fees may be charged\n                   └─ Acceleration/charge-off threshold checked\n"},"children":[]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"appendix-b-grace-period-for-lines-of-credit-appendix-b-grace-period-for-lines-of-credit","__idx":111},"children":["Appendix B: Grace Period for Lines of Credit {#appendix-b-grace-period-for-lines-of-credit}"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Grace periods allow borrowers to avoid paying interest when they pay their full statement balance by the due date. Understanding grace is essential for migration because incorrectly initialized grace status will cause Peach to accrue interest when it shouldn't — or fail to accrue interest when it should."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"what-grace-period-means","__idx":112},"children":["What grace period means"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A grace period is a window during which ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["no interest accrues"]}," on a balance, provided the borrower pays the full statement balance by the due date. This is a regulatory concept common in credit cards."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The rules are:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Pay in full by due date"]}," → grace continues; no interest on that balance for the period"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Don't pay in full"]}," → grace is lost; interest accrues retroactively on the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["unpaid portion"]}," from the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["statement date"]}," (not the due date)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["To restore grace"]}," → pay in full for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]}," consecutive periods"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"daily-grace-tracking-isgraceperiodeligible","__idx":113},"children":["Daily grace tracking (isGracePeriodEligible)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Grace is tracked via a boolean flag (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isGracePeriodEligible"]},") on each obligation. DLM checks this flag every day to decide whether to accrue interest:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"if draw.isGracePeriodApplicable == true\n  AND obligation.isGracePeriodEligible == true\n  → DO NOT accrue interest for this day\nelse\n  → accrue interest normally\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The system carries the prior day's grace status forward as a default and updates it on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate + 1"]}," (see below)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"the-due-date--1-check","__idx":114},"children":["The due date + 1 check"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The critical decision point for grace is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["one day after the due date"]},". This is when Peach evaluates whether the borrower paid in full, and either revokes or reinstates grace."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["If the borrower paid in full"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fulfilledByDueDateAmount >= fullBalanceAmount"]},"):"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If already in grace → no change (grace continues)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If not in grace → check the past ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace - 1"]}," obligations. If all of them were also paid in full, ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["reinstate grace"]},": set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isGracePeriodEligible = true"]}," and trigger a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["replay"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["period.startDate"]},". The replay retroactively removes interest that was accrued while grace was ineligible."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["If the borrower did NOT pay in full"]}," and the obligation was grace-eligible:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Revoke grace"]},": set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isGracePeriodEligible = false"]}," and trigger a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["replay"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["period.startDate"]},". The replay retroactively accrues interest on the unpaid portion from the statement date forward."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," When grace is revoked, the retroactive interest charge can be large if the borrower had been in grace with a high balance. The interest accrues on the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["unpaid balance"]}," from the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["statement date"]},", not the due date. Make sure borrower communications explain this behavior."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"numperiodstorestoregrace-and-the-migration-override","__idx":115},"children":["numPeriodsToRestoreGrace and the migration override"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After grace is revoked, the borrower must pay in full for N consecutive periods to regain eligibility. This is controlled by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]}," (typically configured on the draw or loan type)."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Migration override"]},": For the migration previous period, Peach overrides ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]}," to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["1"]}," regardless of the configured value. This means a borrower who lost grace before migration only needs to pay in full for one period post-migration to restore it. The override exists because Peach does not have per-draw grace history for pre-migration periods and defaults to the behavior most favorable to the borrower."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The configured ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace"]}," takes full effect starting in the period after migration."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"transaction-effective-date-manipulation","__idx":116},"children":["Transaction effective date manipulation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When a payment is applied between ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["statementDate"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}," on a draw that is grace-eligible, Peach manipulates the transaction's effective date:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"transaction.effectiveDate = obligation.statementDate  (backdated)\ntransaction.displayDate = actual_payment_date          (for customer statements)\n→ replay from period.startDate\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This ensures that the interest calculation treats the payment as if it was made on the statement date. Without this, a payment on due date - 5 would leave 5 days of interest unaddressed in the calculation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"grace-adjustment-for-refunds-and-cashbacks","__idx":117},"children":["Grace adjustment for refunds and cashbacks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a refund or cashback is issued between the statement date and the due date, it reduces the amount the borrower needs to pay to maintain grace:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"effectiveFullBalance = fullBalanceAmount - adjustmentAfterStatementAmount\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For example: if the statement balance is $1,000 and a $200 merchant refund is issued before the due date, the borrower only needs to pay $800 by the due date to keep grace."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"loan-level-vs-draw-level-grace","__idx":118},"children":["Loan-level vs. draw-level grace"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Grace can be tracked at two levels:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Level"},"children":["Level"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Configuration"},"children":["Configuration"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Behavior"},"children":["Behavior"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Loan-level"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loc.isGracePeriodApplicable = true"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["All draws share one grace status. If any draw loses grace, the entire LOC loses grace."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Draw-level"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["draw.atOrigination.gracePeriod.isGracePeriodApplicable = true"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Each draw tracks grace independently."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During migration, the system sets loan-level grace based on the aggregate of all draw-level grace statuses: if all draws are grace-eligible, the LOC is grace-eligible."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-this-matters-for-migration-1","__idx":119},"children":["Why this matters for migration"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isGracePeriodEligible"]}," correctly"]}," in the migration period data. If the borrower was in grace before migration, set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},". If they had lost grace, set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Record the grace balance"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gracePeriod.fullBalanceAmount"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gracePeriod.fulfilledByDueDateAmount"]},") accurately. These determine whether the due date + 1 check revokes or reinstates grace."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["If grace is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}]},", understand that post-migration interest will accrue retroactively from the statement date of the migration period — which may create a significant interest charge on the first post-migration statement."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["The migration override"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["numPeriodsToRestoreGrace = 1"]},") means borrowers who lost grace before migration can regain it after just one on-time full payment post-migration, even if the loan type normally requires multiple consecutive periods."]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"appendix-c-loc-draws--how-they-work","__idx":120},"children":["Appendix C: LOC Draws — How They Work"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A draw is a sub-account within a line of credit. Each draw has its own balance, interest rate, fee structure, and transaction history. Draws allow borrowers to segregate different types of borrowing (e.g., purchases at one rate, cash advances at a higher rate) within a single credit line."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"what-is-a-draw","__idx":121},"children":["What is a draw?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A draw is a virtual \"bucket\" within the LOC. When a purchase is posted or a cash advance is taken, it is assigned to a specific draw. The LOC's total credit limit is shared across all active draws, but each draw independently maintains its own balance, interest rate, promotional rate, draw fees, and minimum payment calculation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"draw-types","__idx":122},"children":["Draw types"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Peach supports four draw types:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Draw type"},"children":["Draw type"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Purpose"},"children":["Purpose"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Typical use"},"children":["Typical use"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Interest behavior"},"children":["Interest behavior"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["RegularPurchase"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Standard retail purchases"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Primary draw type for card activity"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Standard APR"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["CashAdvance"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Cash withdrawal or equivalent"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["ATM withdrawals, cash-like transactions"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Often higher APR; may have different fees"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["BalanceTransfer"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Transferred balance from another card"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Promotional offers"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Often 0% APR promotional rate"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Static"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Migration draw (historical data)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Created automatically at migration"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["No interest accrual; no new activity after migration"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Most active LOCs have multiple draws. The ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Static"]}," draw is special and used only during migration."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"how-draws-share-the-credit-limit","__idx":123},"children":["How draws share the credit limit"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The LOC has a single credit limit (e.g., $10,000) that applies across all draws:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"available_credit = loc.creditLimit - sum(draw.balance for all active draws)\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each draw can also have a sub-limit that further restricts that specific draw type. Both the LOC-level limit and the draw-level limit must be satisfied for a new purchase to be approved."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"draw-fees-1","__idx":124},"children":["Draw fees"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Fees can be charged at draw creation or throughout the draw's lifecycle:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Fee type"},"children":["Fee type"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"When charged"},"children":["When charged"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Example"},"children":["Example"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Draw fee"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["At draw creation"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["$75 cash advance origination fee"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Transaction fee"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Per transaction"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["3% foreign transaction fee"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Periodic fee"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Each billing period"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["$5/month servicing fee"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Late fee"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["When draw goes overdue"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Automatic, handled by DLM"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Draw fees are tracked separately from LOC-level fees (like annual fees). During migration, draw fee balances must be included in the migration period draw data under the appropriate ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nonDueDrawFeesAmount"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDrawFeesAmount"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overdueDrawFeesAmount"]}," fields."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"how-purchases-are-associated-with-draws","__idx":125},"children":["How purchases are associated with draws"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When a purchase is posted, it must be assigned to a specific draw. The assignment determines which draw's balance increases, which interest rate applies, and which minimum payment calculation is used."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During migration, historical purchases are posted to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["migration draw"]}," (static draw) with an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originalDrawId"]}," field referencing the actual legacy draw they belonged to. Post-migration, new purchases are posted directly to the appropriate draw (RegularPurchase, CashAdvance, etc.)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"static-draw-migration-draw","__idx":126},"children":["Static draw (migration draw)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The static draw is an internal construct created at migration to hold all pre-migration transactions and balances. It exists solely to bootstrap the LOC with historical data."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Creation:"]}," Peach automatically creates one static draw per LOC when the loan is created with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migrationStatus: \"prepMigration\""]},". You don't create it manually."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Configuration:"]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Property"},"children":["Property"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Value"},"children":["Value"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Why"},"children":["Why"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drawType"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Static"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Identifies it as the migration draw"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timestamps"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Equal to LOC activation date"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Appears to have existed since LOC origination"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["min_payment_percentage_of_principal"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["0"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Static draw doesn't contribute to minimum payment"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["migration_status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Synced with LOC"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Follows the LOC's migration lifecycle"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["What it holds:"]}," All pre-migration purchases, transactions (payments, service credits), fees, and obligations."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Behavior after migration:"]}," The static draw transitions to Active status (like all other draws) but is effectively disabled — the API rejects any attempt to post new activity to a static draw with \"This endpoint is invalid for a static draw.\" Payment application can still target the static draw if the borrower carries an unpaid balance from pre-migration."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originalDrawId"]}," field on historical purchases references the actual legacy draw, not the static draw. This lets you track which legacy draw each purchase belonged to, even though all historical purchases are stored under the static draw in Peach."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"minimum-payment-calculation","__idx":127},"children":["Minimum payment calculation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The LOC's minimum payment is the sum of each draw's minimum payment:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"loc.minimumPayment = sum(draw.principal * draw.minPaymentPercentage for all active draws)\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The percentage can vary by draw type (e.g., CashAdvance might require 5% while RegularPurchase requires 2%). The static draw's percentage is 0, so it contributes nothing to the minimum payment. This prevents borrowers from facing unexpectedly high minimums immediately after migration due to old balances."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-this-matters-for-migration-2","__idx":128},"children":["Why this matters for migration"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["The static draw is created automatically"]}," — don't create it manually."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Post all historical purchases to the static draw"]}," using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["originalDrawId"]}," to reference the actual legacy draw."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Create actual draws"]}," (RegularPurchase, CashAdvance, etc.) for any draw types that were active before migration and should continue to accept new activity."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Populate migration period data for each draw"]}," — the system validates that every non-static draw has a ledger update event."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["After migration"]},", all new activity goes to actual draws. The static draw is read-only."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Draw fees"]}," must be configured correctly on each draw's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["atOrigination.fees"]}," object, and fee balances must be seeded in the migration period draw data."]}]}]},"headings":[{"value":"Line of Credit Migration Guide","id":"line-of-credit-migration-guide","depth":1},{"value":"Introduction","id":"introduction","depth":2},{"value":"How LOC migration differs from installment migration","id":"how-loc-migration-differs-from-installment-migration","depth":2},{"value":"Key concepts","id":"key-concepts","depth":2},{"value":"Migration period","id":"migration-period","depth":3},{"value":"Migration cutoff date","id":"migration-cutoff-date","depth":3},{"value":"Migration draw (static draw)","id":"migration-draw-static-draw","depth":3},{"value":"Past periods data","id":"past-periods-data","depth":3},{"value":"Historical vs. live activity","id":"historical-vs-live-activity","depth":3},{"value":"Grace period eligibility","id":"grace-period-eligibility","depth":3},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"1. Set up a sandbox environment","id":"1-set-up-a-sandbox-environment","depth":3},{"value":"2. Configure your loan type","id":"2-configure-your-loan-type","depth":3},{"value":"3. Configure fee types","id":"3-configure-fee-types","depth":3},{"value":"4. Prepare your legacy data","id":"4-prepare-your-legacy-data","depth":3},{"value":"5. Plan your migration timing","id":"5-plan-your-migration-timing","depth":3},{"value":"Step 1: Create the borrower and payment methods","id":"step-1-create-the-borrower-and-payment-methods","depth":2},{"value":"Create borrower","id":"create-borrower","depth":3},{"value":"Create contact records","id":"create-contact-records","depth":3},{"value":"Create payment instruments","id":"create-payment-instruments","depth":3},{"value":"Step 2: Create and configure the line of credit","id":"step-2-create-and-configure-the-line-of-credit","depth":2},{"value":"Create the loan","id":"create-the-loan","depth":3},{"value":"Retrieve the migration draw","id":"retrieve-the-migration-draw","depth":3},{"value":"Create active draws","id":"create-active-draws","depth":3},{"value":"Upload loan documents","id":"upload-loan-documents","depth":3},{"value":"Step 3: Populate historical data","id":"step-3-populate-historical-data","depth":2},{"value":"Create past periods data","id":"create-past-periods-data","depth":3},{"value":"Create migration period LOC data","id":"create-migration-period-loc-data","depth":3},{"value":"Create migration period draw data","id":"create-migration-period-draw-data","depth":3},{"value":"Change loan status to Originated","id":"change-loan-status-to-originated","depth":3},{"value":"Step 4: Create activities","id":"step-4-create-activities","depth":2},{"value":"Historical purchases (before the migration cutoff date)","id":"historical-purchases-before-the-migration-cutoff-date","depth":3},{"value":"Live purchases (on or after the migration cutoff date)","id":"live-purchases-on-or-after-the-migration-cutoff-date","depth":3},{"value":"Historical transactions (before the migration cutoff date)","id":"historical-transactions-before-the-migration-cutoff-date","depth":3},{"value":"Live transactions (on or after the migration cutoff date)","id":"live-transactions-on-or-after-the-migration-cutoff-date","depth":3},{"value":"Historical fees (before the migration cutoff date)","id":"historical-fees-before-the-migration-cutoff-date","depth":3},{"value":"Live fees (on or after the migration cutoff date)","id":"live-fees-on-or-after-the-migration-cutoff-date","depth":3},{"value":"Step 5: Execute migration","id":"step-5-execute-migration","depth":2},{"value":"Call the migrate endpoint","id":"call-the-migrate-endpoint","depth":3},{"value":"Monitor migration status","id":"monitor-migration-status","depth":3},{"value":"What happens during migration","id":"what-happens-during-migration","depth":3},{"value":"If migration succeeds","id":"if-migration-succeeds","depth":3},{"value":"If migration fails","id":"if-migration-fails","depth":3},{"value":"Step 6: Post-migration","id":"step-6-post-migration","depth":2},{"value":"Validate balances","id":"validate-balances","depth":3},{"value":"Adjust balances","id":"adjust-balances","depth":3},{"value":"Configure autopay","id":"configure-autopay","depth":3},{"value":"Re-enable borrower communications {#re-enable-borrower-communications}","id":"re-enable-borrower-communications-re-enable-borrower-communications","depth":3},{"value":"Set up credit reporting","id":"set-up-credit-reporting","depth":3},{"value":"System behavior after migration succeeds","id":"system-behavior-after-migration-succeeds","depth":3},{"value":"When daily loan maintenance (DLM) starts","id":"when-daily-loan-maintenance-dlm-starts","depth":4},{"value":"First post-migration statement","id":"first-post-migration-statement","depth":4},{"value":"Snapshot backfill","id":"snapshot-backfill","depth":4},{"value":"How ongoing activity works","id":"how-ongoing-activity-works","depth":4},{"value":"What happens at the next billing cycle boundary","id":"what-happens-at-the-next-billing-cycle-boundary","depth":4},{"value":"What you can and can't change after migration {#what-you-can-and-cant-change-after-migration}","id":"what-you-can-and-cant-change-after-migration-what-you-can-and-cant-change-after-migration","depth":3},{"value":"Supported modifications","id":"supported-modifications","depth":4},{"value":"Constraints on modifications","id":"constraints-on-modifications","depth":4},{"value":"What the system won't let you do","id":"what-the-system-wont-let-you-do","depth":4},{"value":"System design constraints and known behaviors","id":"system-design-constraints-and-known-behaviors","depth":3},{"value":"Grace period override during migration","id":"grace-period-override-during-migration","depth":4},{"value":"DPD calculation for migrated loans","id":"dpd-calculation-for-migrated-loans","depth":4},{"value":"No loan tapes for pre-migration periods","id":"no-loan-tapes-for-pre-migration-periods","depth":4},{"value":"Past-transaction drawSplitDetails access","id":"past-transaction-drawsplitdetails-access","depth":4},{"value":"Balance precision and credit balance handling","id":"balance-precision-and-credit-balance-handling","depth":4},{"value":"Statement date must be endDate + 1","id":"statement-date-must-be-enddate--1","depth":4},{"value":"Effective time of day minimum","id":"effective-time-of-day-minimum","depth":4},{"value":"Overdue amount and days overdue consistency","id":"overdue-amount-and-days-overdue-consistency","depth":4},{"value":"Interest rounding for LOCs","id":"interest-rounding-for-locs","depth":4},{"value":"Origination and draw fees","id":"origination-and-draw-fees","depth":2},{"value":"Origination fees","id":"origination-fees","depth":3},{"value":"Draw fees","id":"draw-fees","depth":3},{"value":"Statement and due date configuration","id":"statement-and-due-date-configuration","depth":2},{"value":"Modifying historical data post-migration","id":"modifying-historical-data-post-migration","depth":2},{"value":"Dispute historical purchases","id":"dispute-historical-purchases","depth":3},{"value":"Waive or cancel historical fees","id":"waive-or-cancel-historical-fees","depth":3},{"value":"Change historical transaction status","id":"change-historical-transaction-status","depth":3},{"value":"Reverse historical transactions","id":"reverse-historical-transactions","depth":3},{"value":"Correct and re-create purchases or transactions","id":"correct-and-re-create-purchases-or-transactions","depth":3},{"value":"Migrating special loan states","id":"migrating-special-loan-states","depth":2},{"value":"Delinquent loans","id":"delinquent-loans","depth":3},{"value":"Accelerated and charged-off loans","id":"accelerated-and-charged-off-loans","depth":3},{"value":"Migration strategy and operations","id":"migration-strategy-and-operations","depth":2},{"value":"Batching and segmentation","id":"batching-and-segmentation","depth":3},{"value":"Borrower communications during migration","id":"borrower-communications-during-migration","depth":3},{"value":"Concurrent system operation","id":"concurrent-system-operation","depth":3},{"value":"Canceling and re-migrating loans","id":"canceling-and-re-migrating-loans","depth":3},{"value":"Validation rules and common errors","id":"validation-rules-and-common-errors","depth":2},{"value":"Period validation","id":"period-validation","depth":3},{"value":"Transaction validation","id":"transaction-validation","depth":3},{"value":"Balance validation","id":"balance-validation","depth":3},{"value":"Troubleshooting and FAQ","id":"troubleshooting-and-faq","depth":2},{"value":"Balance discrepancies","id":"balance-discrepancies","depth":3},{"value":"Principal/interest split differences","id":"principalinterest-split-differences","depth":3},{"value":"Interest calculation after grace period revocation","id":"interest-calculation-after-grace-period-revocation","depth":3},{"value":"Loan tapes after migration","id":"loan-tapes-after-migration","depth":3},{"value":"Migration processing time","id":"migration-processing-time","depth":3},{"value":"Failed migration with no errors","id":"failed-migration-with-no-errors","depth":3},{"value":"Re-using external IDs after cancellation","id":"re-using-external-ids-after-cancellation","depth":3},{"value":"Sandbox testing","id":"sandbox-testing","depth":3},{"value":"Migration validation errors","id":"migration-validation-errors","depth":3},{"value":"Webhook events","id":"webhook-events","depth":2},{"value":"API quick reference","id":"api-quick-reference","depth":2},{"value":"Appendix A: LOC Billing Cycle Mechanics {#appendix-a-loc-billing-cycle-mechanics}","id":"appendix-a-loc-billing-cycle-mechanics-appendix-a-loc-billing-cycle-mechanics","depth":2},{"value":"Billing period structure","id":"billing-period-structure","depth":3},{"value":"Balance movement: non-due → due → overdue","id":"balance-movement-non-due--due--overdue","depth":3},{"value":"Non-due to due (statement date)","id":"non-due-to-due-statement-date","depth":4},{"value":"Due to overdue (due date + 1)","id":"due-to-overdue-due-date--1","depth":4},{"value":"Obligations: tracking what the borrower owes","id":"obligations-tracking-what-the-borrower-owes","depth":3},{"value":"Why this matters for migration","id":"why-this-matters-for-migration","depth":3},{"value":"Timeline example","id":"timeline-example","depth":3},{"value":"Appendix B: Grace Period for Lines of Credit {#appendix-b-grace-period-for-lines-of-credit}","id":"appendix-b-grace-period-for-lines-of-credit-appendix-b-grace-period-for-lines-of-credit","depth":2},{"value":"What grace period means","id":"what-grace-period-means","depth":3},{"value":"Daily grace tracking (isGracePeriodEligible)","id":"daily-grace-tracking-isgraceperiodeligible","depth":3},{"value":"The due date + 1 check","id":"the-due-date--1-check","depth":3},{"value":"numPeriodsToRestoreGrace and the migration override","id":"numperiodstorestoregrace-and-the-migration-override","depth":3},{"value":"Transaction effective date manipulation","id":"transaction-effective-date-manipulation","depth":3},{"value":"Grace adjustment for refunds and cashbacks","id":"grace-adjustment-for-refunds-and-cashbacks","depth":3},{"value":"Loan-level vs. draw-level grace","id":"loan-level-vs-draw-level-grace","depth":3},{"value":"Why this matters for migration","id":"why-this-matters-for-migration-1","depth":3},{"value":"Appendix C: LOC Draws — How They Work","id":"appendix-c-loc-draws--how-they-work","depth":2},{"value":"What is a draw?","id":"what-is-a-draw","depth":3},{"value":"Draw types","id":"draw-types","depth":3},{"value":"How draws share the credit limit","id":"how-draws-share-the-credit-limit","depth":3},{"value":"Draw fees","id":"draw-fees-1","depth":3},{"value":"How purchases are associated with draws","id":"how-purchases-are-associated-with-draws","depth":3},{"value":"Static draw (migration draw)","id":"static-draw-migration-draw","depth":3},{"value":"Minimum payment calculation","id":"minimum-payment-calculation","depth":3},{"value":"Why this matters for migration","id":"why-this-matters-for-migration-2","depth":3}],"frontmatter":{"seo":{"title":"Line of Credit Migration Guide"}},"lastModified":"2026-05-01T14:33:55.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/loan-lifecycle/loc-migration-guide","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}