Most bugs in distributed .NET systems don’t come from bad algorithms — they come from drift.
The UI expects one shape of data, the API returns another, and tests quietly fall out of sync. Each layer evolves independently until something breaks in production.
Contract-based development flips that dynamic. Instead of treating DTOs as disposable plumbing, it makes them the source of truth — shared, versioned, and enforced across Blazor SSR, WASM, Minimal APIs, and tests.
In this article, we’ll walk through a practical, end-to-end approach to contract-based development in .NET 10, which demonstrateshow development teams define DTOs once, reuse them everywhere, and build systems that evolve safely without constant firefighting.
The Problem: Drift Between Client and Server
In most .NET systems, client and server don’t break all at once… they drift.
A field is renamed in the API. The UI keeps compiling. Tests still pass. Production quietly breaks.
This happens because data contracts are often treated as implementation details, not as first-class citizens. DTOs get duplicated, reshaped, or redefined in each layer — API, UI, and tests — with the assumption that “we’ll keep them in sync.”
In reality, they rarely stay that way.
As systems grow, this drift shows up as:
Mapping logic scattered everywhere
UI models that don’t quite match API responses
Breaking changes discovered late or not at all
Fear of touching shared code
The result isn’t just bugs, it’s lost confidence. Developers hesitate to refactor. Features take longer to ship. Small changes carry unexpected risk.
Contract-based development exists to stop this drift. By defining DTOs once and treating them as stable boundaries, teams regain control over how systems evolve… deliberately, predictably, and safely.
What Contract-Based Development Actually Means
Contract-based development is simple in concept, but powerful in practice:
The DTO is the contract.
Instead of being a temporary shape used to move data between layers, a DTO becomes a deliberate boundary that both the client and the server agree on. Every layer — Blazor SSR, Blazor WASM, Minimal APIs, handlers, and tests — depends on that contract staying stable.
This is different from:
Copying DTOs into multiple projects
“Shared models” with unclear ownership
Letting domain models leak across boundaries
In contract-based development:
DTOs are defined once
Changes are intentional and visible
Breaking changes surface at compile time, not in production
The contract doesn’t own business logic. It owns shape and intent. It answers questions like:
What data is allowed to cross this boundary?
What does the client expect?
What guarantees does the server provide?
Everything else adapts to the contract, not the other way around.
This approach creates a natural forcing function: If a contract changes, every affected layer must acknowledge it. That friction is intentional. It’s how teams prevent silent breakage and accidental drift.
Defining DTOs Once (and Owning Them)
The most important rule of contract-based development is also the simplest:
Define your DTOs once, and give them a clear owner.
In many systems, DTOs are scattered and even duplicated across API projects, UI projects, and test assemblies. Each copy starts identical, then slowly diverges. That’s how drift begins.
Development teams avoid this by creating a dedicated contracts project whose sole responsibility is to define stable data shapes.
It exists to answer one question: What data is allowed to cross system boundaries?
Why Ownership Matters
When DTOs live in a shared, intentional location:
Changes are explicit and visible
Breaking changes fail fast at compile time
Teams stop “just adding a field” casually
Refactoring becomes safer, not scarier
The contracts project becomes a stability anchor. Everything else — APIs, Blazor components, handlers, tests — depends on it, not the other way around.
What Belongs in a DTO (and What Doesn’t)
DTOs should represent shape and intent, not behavior.
They are ideal for:
API request and response models
UI data binding
Serialization boundaries
Test fixtures
They should not contain:
Business rules
Persistence logic
Domain invariants
That separation keeps contracts stable even as internal implementations change.
Using the Same DTO Everywhere (Without Regret)
Once DTOs are defined and owned, the real payoff comes from using them end-to-end — unchanged — across the entire stack.
This is where contract-based development stops being a theory and starts saving real time.
Minimal APIs: Contracts at the Boundary
Minimal APIs pair naturally with DTOs because they keep the boundary explicit.
app.MapPost("/users", async ( CreateUserDto dto, IMediator mediator) => { var result = await mediator.Send(new CreateUserCommand(dto)); return Results.Ok(result); });
What this gives you:
The API surface is self-documenting
Model binding is predictable
Breakingchanges surface immediately
No hidden mapping layers
The DTO is the contract — nothing more, nothing less.
And when used correctly, it is a win — especially in contract-driven systems.
Why We Care About Source Generation
Source generation is a compile-time technique where tooling analyzes your code and automatically generates additional C# source files that become part of your application… without runtime reflection.
Traditional reflection-based serialization is:
Flexible
Convenient
Opaque
Source generation flips that:
Explicit contracts
Compile-time validation
Predictable behavior
That predictability is what makes it attractive for DTO-heavy systems.
Defining the Serialization Boundary
Source generation starts with declaring exactly which DTOs are part of your public contract.
[JsonSerializable(typeof(CreateUserDto))] [JsonSerializable(typeof(UserDto))] public partial class ApiJsonContext : JsonSerializerContext { }
This does two important things:
Locks down what gets serialized
Prevents accidental surface-area growth
If a DTO isn’t listed, it doesn’t magically start flowing through your API.
That’s intentional.
Wiring It into Minimal APIs
Minimal APIs make it easy to opt into source-generated serialization.
This code makes HttpClient use source-generated JSON converters first, which improves performance, safety, and compile-time validation when sending/receiving DTOs.
Uses source-generated JSON serialization instead of reflection-based serialization.
Ensures predictable, fast, and type-safe serialization for your DTOs.
Overrides default serialization behavior for your HttpClientrequests/responses.
From this point forward:
All matching DTOs use generated serializers
Reflection is avoided
Runtime surprises disappear
If you break a contract, the compiler tells you.
Why This Improves Stability
Source generation forces discipline:
DTO shape changes are explicit
Serialization behavior is visible
Performance characteristics are predictable
You don’t accidentally serialize:
Private fields
Navigation properties
Lazy-loaded graphs
Only what you declared and nothing more.
Where We Draw the Line
Not everything needs source generation.
Development teams usually:
Apply it at API boundaries to enforce contract stability.
Avoid it in UI-only models where flexibility matters more than strict serialization.
Skip it for highly dynamic payloads to reduce unnecessary complexity.
Why?
Configuration overhead: Setting up source generation requires extra project setup and maintenance.
Tooling friction: Some editors and debugging tools don’t handle generated serializers as seamlessly.
Reduced flexibility: Dynamic or evolving payloads can’t leverage source generation without extra work.
The rule is simple:
If it’s a contract, generate it. If it’s internal, keep it flexible.
Testing the Generated Contract
Because serializers are generated at compile time, tests become simpler and more trustworthy.
var json = JsonSerializer.Serialize(dto, ApiJsonContext.Default.UserDto); var roundTrip = JsonSerializer.Deserialize<UserDto>(json, ApiJsonContext.Default.UserDto);
roundTrip.Should().BeEquivalentTo(dto);
This guarantees:
Symmetry: Serialization and deserialization behave predictably, ensuring no accidental data loss.
Compatibility: Changes to the DTO surface are caught immediately, preventing runtime mismatches.
Long-term stability: Contracts remain reliable over time, reducing regression risk and build-time surprises.
No reflection magic. No surprises after deployment.
Why This Ages Well
Source-generated JSON doesn’t just improve performance — it reinforces stability across the system. Here’s why senior developers love it:
Shared DTOs: Because DTOs are defined once and used everywhere, source generation ensures every boundary respects the same shape, reducing the risk of drift.
Minimal APIs: At API boundaries, source-generated serialization makes intent explicit, avoiding hidden surprises and keeping endpoints predictable.
Vertical slice architectures: Each feature slice can depend on its own clearly defined contracts, letting handlers, endpoints, and UI components share the same DTOs safely.
AOT scenarios: Ahead-of-Time compilation benefits from predictable serialization patterns, making startup and runtime behavior faster and more reliable.
It trades flexibility for clarity — and that’s a trade developers are happy to make at system boundaries.
Testing DTO Boundaries to Guarantee Stability
Defining and sharing DTOs is only half the battle. The other half is testing them like first-class citizens. When contracts are enforced at compile time and verified through tests, teams gain confidence — they can refactor, ship features, and onboard new developers without fear.
Why Test Contracts
Even with source-generated serialization, mistakes can slip through:
Fields may be added or removed accidentally
Mapping mistakes could break APIs
Round-trip serialization may differ between client and server
By testing DTOs, you catch these issues before deployment, not after users notice.
var json = JsonSerializer.Serialize(dto, ApiJsonContext.Default.CreateUserDto); var roundTrip = JsonSerializer.Deserialize<CreateUserDto>(json, ApiJsonContext.Default.CreateUserDto);
roundTrip.Should().BeEquivalentTo(dto);
This guarantees:
Symmetry:Serialized and deserialized objects match exactly
Compatibility: Changes to DTOs surface immediately
Long-term stability:Contracts remain reliable over time
Integration and API Tests
DTOs can also be validated through Minimal API or Blazor integration tests:
var response = await client.PostAsJsonAsync("/users", dto); response.EnsureSuccessStatusCode();
If a contract drifts, the test fails. Developers know immediately where the problem lies.
Why This Matters
Development teams understand that the real value of contract-based development isn’t just code organization — it’s confidence at scale. With proper DTO testing:
Refactors are safe
Cross-team collaboration is easier
Production bugs decrease
Testing DTO boundaries turns the contract from a theoretical agreement into a guaranteed, verifiable safety net.
How This Supports Blazor Auto Mode
Blazor Auto Mode is the new hybrid standard in .NET 10, combining SSR (Server-Side Rendering) and WASM (WebAssembly) seamlessly. Contract-based development makes this transition effortless.
Why DTOs Matter in Auto Mode
In Auto Mode:
SSR renders the page server-side for fast first paint
WASM runtime downloads for full interactivity
State must stay consistent across both environments
DTOs act as the single source of truth, ensuring the data shape is identical for SSR and WASM. Without stable contracts, the UI risks mismatches, hydration errors, or subtle runtime bugs.
Here, the same UserDto flows from Minimal API → MediatR Handler → EF Core → SSR page → WASM page.
No mapping. No drift. No surprises.
Why This Works End-to-End
SSR first paint: Users see content immediately
Hydration consistency: WASM picks up the same contract, preventing UI glitches
Real-time updates: SignalR or other streaming data can continue to use the same DTOs
Testable boundaries: Both server and client tests validate the same data shape
The Developer Advantage
By combining DTO-driven contracts with Blazor Auto Mode:
You avoid duplicate UI models
You reduce hydration bugs
You maintain predictable, testable state across SSR and WASM
You make refactoring safe even in large, complex applications
Contracts aren’t just for APIs anymore. They’re the backbone of modern, full-stack .NET 10 applications.
End-to-End Example: From Page to Database
To see contract-based development in action, let’s walk through a full feature: creating a user, from the Blazor page to the database and back, including real-time updates.
Step 1: The DTO (Contract)
public record CreateUserDto(string Email, string FirstName, string LastName); public record UserDto(Guid Id, string Email, string FirstName, string LastName);
CreateUserDto defines the input for creating a user
UserDto defines the output that flows through API, Blazor, and tests
Step 2: Minimal API Endpoint
app.MapPost("/users", async ( CreateUserDto dto, IMediator mediator) => { var result = await mediator.Send(new CreateUserCommand(dto)); return Results.Ok(result); });
The endpoint is thin and readable
No business logic here. It delegates to the handler
Step 3: MediatR Command and Handler
public record CreateUserCommand(CreateUserDto Dto) : IRequest<UserDto>;
public class CreateUserHandler : IRequestHandler<CreateUserCommand, UserDto> { private readonly AppDbContext _db;
public CreateUserHandler(AppDbContext db) => _db = db;
public async Task<UserDto> Handle(CreateUserCommand command, CancellationToken ct) { var user = new User(command.Dto.Email, command.Dto.FirstName, command.Dto.LastName); await _db.Users.AddAsync(user, ct); await _db.SaveChangesAsync(ct); return user.ToDto(); } }
Clients subscribe without worrying about shape mismatches
Step 6: Testing the Full Flow
var dto = new CreateUserDto("[email protected]", "John", "Doe"); var response = await client.PostAsJsonAsync("/users", dto); response.EnsureSuccessStatusCode();
var created = await response.Content.ReadFromJsonAsync<UserDto>(); created.Should().NotBeNull(); created.Email.Should().Be(dto.Email);
Test verifies contract symmetry
Ensures API, database, and UI all agree
Why This Works
Single source of truth:DTOs define boundaries, not behavior
Thin endpoints:Minimal APIs delegate, handlers own features
Predictable full-stack flow: Blazor SSR/WASM, API, SignalR, and tests all align
Testable and maintainable: Refactoring is safe, onboarding is easy
This is the practical payoff of contract-based development in modern .NET 10 systems.
Contracts Are the Backbone of Modern .NET
Across Minimal APIs, Blazor SSR/WASM, MediatR, DTOs, source-generated JSON, and even SignalR, a clear pattern emerges: stability beats novelty. Developers don’t chase every shiny feature, they adopt tools that make systems easier to reason about, easier to test, and easier to evolve over time.
Contract-based development enforces a single source of truth. DTOs define the boundaries, handlers own the features, and endpoints remain thin and predictable. The result is a full-stack system that scales, reduces cognitive overhead, and survives refactors without breaking a sweat.
By defining contracts once, using them everywhere, generating serializers selectively, and testing boundaries thoroughly, teams gain confidence at scale.
The takeaway: Build your system around explicit, testable contracts. The code that survives isn’t the flashiest — it’s the most deliberate.
{"id":"2","mode":"button","open_style":"in_modal","currency_code":"USD","currency_symbol":"$","currency_type":"decimal","blank_flag_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":500,"top_media_type":"featured_image","featured_image_url":"https:\/\/robhutton.com\/wp-content\/uploads\/Screenshot-2025-02-19-163019-100x74.png","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":false,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Tip Jar","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"robhutton.com","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"robhutton.com","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for being a supporter!","payment_confirmation_title":"robhutton.com","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":"Voluntary nature: Tips are non-refundable and given voluntarily. No goods\/services in exchange: Tipping doesn\u2019t entitle the user to any product, service, or preferential treatment. Payment processing: Mention that payments are processed securely through a third-party provider. No liability: You aren\u2019t responsible for transaction failures, fraud, or technical issues.","terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}
{"id":"4","mode":"text_link","open_style":"in_modal","currency_code":"USD","currency_symbol":"$","currency_type":"decimal","blank_flag_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":500,"top_media_type":"featured_image","featured_image_url":"https:\/\/robhutton.com\/wp-content\/uploads\/Screenshot-2025-02-19-163019-100x74.png","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":true,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Like my articles? Tips are appreciated.","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for being a supporter!","payment_confirmation_title":"","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":"Voluntary nature: Tips are non-refundable and given voluntarily. No goods\/services in exchange: Tipping doesn\u2019t entitle the user to any product, service, or preferential treatment. Payment processing: Mention that payments are processed securely through a third-party provider. No liability: You aren\u2019t responsible for transaction failures, fraud, or technical issues.","terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}