Exception in thread "main" java.lang.InternalError: java.lang.reflect.InvocationTargetException at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:86) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74) at java.desktop/sun.font.SunFontManager.getInstance(SunFontManager.java:249) at java.desktop/sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:265) at java.desktop/sun.java2d.SunGraphics2D.getFontMetrics(SunGraphics2D.java:869) at net.sourceforge.plantuml.Run.forceOpenJdkResourceLoad(Run.java:251) at net.sourceforge.plantuml.Run.main(Run.java:155) Caused by: java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:84) ... 7 more Caused by: java.lang.RuntimeException: Fontconfig head is null, check your fonts or fonts configuration at java.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1271) at java.desktop/sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:225) at java.desktop/sun.awt.FontConfiguration.init(FontConfiguration.java:107) at java.desktop/sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:719) at java.desktop/sun.font.SunFontManager$2.run(SunFontManager.java:379) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.desktop/sun.font.SunFontManager.<init>(SunFontManager.java:324) at java.desktop/sun.awt.FcFontManager.<init>(FcFontManager.java:35) at java.desktop/sun.awt.X11FontManager.<init>(X11FontManager.java:56) ... 12 more
In the examples below we use username and password connection.
Create a customer
To create the customer you create first the login and password then you create two contacts BillTo and SoldTo.
BillTo: Contact who receives invoices
SoldTo: Contact who receives the services sold. His address is also used to calculate VAT.
POST http://{{host}}/api/customers
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"login": "{{customer_name}}",
"password": "test"
}
Create contact and link it to the customer with the linker API
POST http://{{host}}/api/contacts
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"gender": 1,
"firstname": "juju",
"lastname": "tt",
"phoneNumber": "0672982651",
"city": "Poitiers",
"country": "FR",
"email": "{{customer_name}}",
"login": "{{customer_name}}",
"password": "test",
"description": "test",
"address1": "7 rue des tilleuls",
"address2": "",
"postalCode": "86000",
"customer": {{customer_id}}
}
POST http://{{host}}/api/linker
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"from_object_type": "Customer",
"from_object_id": {{customer_id}},
"to_object_type": "billTo",
"to_object_id": {{contact_id}}
}
POST http://{{host}}/api/linker
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"from_object_type": "Customer",
"from_object_id": {{customer_id}},
"to_object_type": "soldTo",
"to_object_id": {{contact_id}}
}
Create a subscription for a customer.
Note: the subscription is a prerequisite to bill a customer.
POST http://{{host}}/api/invoiceengine/subscribe
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"customer": {
"login": "{{customer_name}}",
"currency": "EUR"
},
"status": "Active",
"items": [
{
"product_name": "Mix Feeding B2AC",
"product_sku": "B2AC",
"charges": [
{
"model": "PerUnit",
"charge_type": "OneTime",
"per_unit_price": 70,
"quantity": 2,
"billing_period": "Specific Days",
"billing_period_specific_duration": 30,
"billing_timing": "In Advance",
"billing_day": "ChargeTriggerDay",
"charge_name": "Individualized nutrition",
"accounting_code": "",
"accounting_code_number": "",
"tax_mode": "TaxExclusive",
"tax_class": "Taxable"
},
{
"model": "FlatFee",
"flat_fee_price": 70,
"billing_period": "Specific Days",
"billing_period_specific_duration": 30,
"billing_timing": "In Advance",
"billing_day": "ChargeTriggerDay",
"charge_name": "Individualized nutrition",
"accounting_code": "",
"accounting_code_number": "",
"tax_class": "Taxable"
}
],
"custom_fields": [
{
"name": "mode",
"value": "once"
},
{
"name": "recommendation",
"value": "abb69ddf-cab0-44fd-9b51-6528855f5e73"
},
]
}
],
"invoice": true,
"collect": false,
"prepaid_amount": 0,
"incremental_number": "CMDE-2022-03-03-6220a30dcd012",
"contract_effective_date": "2022-03-30",
"service_activation_date": "2022-03-30",
"contract_acceptance_date": "2022-03-30",
"term_type": "EVERGREEN",
"renewal_setting": "RENEW_WITH_SPECIFIC_TERM",
"renewal_term": 1,
"renewal_term_period_type": "Month",
"auto_renew": false,
"invoice_template": "default",
"invoice_number_sequence": "test1",
"invoice_separately": true,
"notification_url": "",
"custom_fields": [
{
"name": "payment_statement_label",
"value": "Valueinpayment"
},
{
"name": "payment_intent_id",
"value": "pi_3KZCbxCIXen1ldHD1Bb55o4PL"
}
]
}
Fields rules:
model: Price model of the product FlatFee, PerUnit, FreeItem -> No invoice generated
per_unit_price: 70.55 (use . as separator)
billing_period: Week , Month, Quarter, Semi-Annual, Annual, Two Years, Specific Days, Specific Weeks, Specific Months
billing_period_specific_duration: 30, (linked to billing_period must be an integer)
billing_timing: In Advance (Start to bill at the beginning of the period), In Arrears: Bill at the end of the period
billing_day: DefaultFromCustomer, SpecificDayOfMonth, SubscriptionStartDay, SpecificDayOfWeek , ChargeTriggerDay, (reference date for the recurring billing)
accounting_code: "", (accounting code name used for sale and sent to the accounting system)
accounting_code_number: "", (accounting code number used for sale and sent to the accounting system)
tax_class: "Taxable" Tax schema to calculate VAT
renewal_setting: RENEW_WITH_SPECIFIC_TERM, RENEW_TO_EVERGREEN
term_type: TERMED, EVERGREEN
Get invoice pdf
GET http://{{host}}/api/invoiceengine/invoice/1/pdf
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
Invoice numbering is the configuration of the numbering for a legal entity
GET http://{{host}}/api/invoiceengine/numberingsequence
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
Configuration of the invoice numbering
POST http://{{host}}/api/invoiceengine/numberingsequence
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"invoice_prefix": "INV",
"invoice_format": "0000-000000",
"invoice_current_value": 12,
"invoice_max_value": 5000,
"start_date": "2022-03-07T00:00:00+00:00",
"end_date": "2032-03-07T00:00:00+00:00",
"code": "provider_233"
}
invoice_format settings
0000-000000 -> you can add year, month, day in the invoice number for that add:
-DD: current day
Update data of the invoice numbering
PUT http://{{host}}/api/invoiceengine/numberingsequence/2
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"invoice_prefix": "INV",
"invoice_format": "0000-000000",
"invoice_current_value": 12,
"invoice_max_value": 5100,
"start_date": "2022-03-07T00:00:00+00:00",
"end_date": "2032-03-07T00:00:00+00:00",
"code": "provider_236"
}
Use the API deletion only on sandbox
DELETE http://{{host}}/api/invoiceengine/numberingsequence/2
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
In the solution you can configure other Payment method means the payment process is managed outside of Valuein or electronic payment method by using payment gateway like Stripe
entityType: otherpaymentmethod (not managed by the billing engine) or stripepaymentmethod (managed by the billing engine with Stripe)
GET http://{{host}}/api/invoiceengine/paymentmethod
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
GET http://{{host}}/api/invoiceengine/paymentmethod/1
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
POST http://{{host}}/api/invoiceengine/paymentmethod
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"customer": "{{customer_id}}",
"entityType": "otherpaymentmethod"
}
POST http://{{host}}/api/invoiceengine/paymentmethod
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"customer": "{{customer_id}}",
"entityType": "stripepaymentmethod",
"token": "test"
}
DELETE http://{{host}}/api/invoiceengine/paymentmethod/2
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
POST http://{{host}}/api/linker
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"from_object_type": "InvoiceEngineBundle:InvoiceEngineCustomer",
"from_object_id": {{customer_id}},
"to_object_type": "defaultPaymentMethod",
"to_object_id": 3
}
POST http://{{host}}/api/invoiceengine/amendment/addProduct
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"incremental_number": "CMDE-2022-03-03-6220a30dcd012",
"items": [
{
"product_name": "Add product2",
"product_sku": "MyVeepCat-B2AC",
"charges": [
{
"model": "PerUnit",
"charge_type": "Recurring",
"per_unit_price": 70,
"quantity": 2,
"billing_period": "Specific Days",
"billing_period_specific_duration": 30,
"billing_timing": "In Advance",
"billing_day": "ChargeTriggerDay",
"charge_name": "Individualized nutrition",
"accounting_code": "",
"accounting_code_number": "",
"tax_mode": "TaxInclusive",
"tax_class": "Taxable"
}
],
"custom_fields": [
]
}
],
"invoice": false,
"collect": false,
"prepaid_amount": 0
}
POST http://{{host}}/api/invoiceengine/amendment/removeProduct
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"incremental_number": "CMDE-2022-05-13",
"product_name": "Mix Feeding B2AC",
"policy": "SpecificDate",
"at_date": "2022-06-07"
}
POST http://{{host}}/api/invoiceengine/amendment/updatePrice
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"incremental_number": "CMDE-2022-05-13",
"product_name": "Mix Feeding B2AC",
"charge_name": "Individualized nutrition",
"new_price": 20,
"from_date": "2022-06-08"
}
POST http://{{host}}/api/invoiceengine/amendment/cancel
Content-Type: application/json
Authorization: Basic {{username}} {{password}}
{
"incremental_number": "CMDE-2022-05-13",
"policy": "EndOfLastInvoicePeriod"
}
Cancellation date policy
policy: EndOfLastInvoicePeriod (ex: end of the month for monthly billing), SpecificDate (specific date set by the subscription strategy or the API call)