diff --git a/Tests/Recurly/CustomFieldDefinitionList_Test.php b/Tests/Recurly/CustomFieldDefinitionList_Test.php
new file mode 100644
index 00000000..5e6b32fe
--- /dev/null
+++ b/Tests/Recurly/CustomFieldDefinitionList_Test.php
@@ -0,0 +1,36 @@
+client->addResponse(
+ 'GET',
+ '/custom_field_definitions',
+ 'custom_field_definitions/list-200.xml'
+ );
+
+ $custom_field_definitions = Recurly_CustomFieldDefinitionList::get(null, $this->client);
+ $this->assertInstanceOf('Recurly_CustomFieldDefinitionList', $custom_field_definitions);
+
+ $custom_field_definition = $custom_field_definitions->current();
+ $this->assertInstanceOf('Recurly_CustomFieldDefinition', $custom_field_definition);
+
+ $this->assertEquals(iterator_count($custom_field_definitions), 3);
+ }
+
+ public function testGetCustomFieldDefinitionListFiltered() {
+ $this->client->addResponse(
+ 'GET',
+ '/custom_field_definitions?related_type=plan',
+ 'custom_field_definitions/list_filtered-200.xml'
+ );
+
+ $custom_field_definitions = Recurly_CustomFieldDefinitionList::getByRelatedType('plan', $this->client);
+ $this->assertInstanceOf('Recurly_CustomFieldDefinitionList', $custom_field_definitions);
+
+ $custom_field_definition = $custom_field_definitions->current();
+ $this->assertInstanceOf('Recurly_CustomFieldDefinition', $custom_field_definition);
+
+ $this->assertEquals(iterator_count($custom_field_definitions), 2);
+ }
+}
diff --git a/Tests/Recurly/CustomFieldDefinition_Test.php b/Tests/Recurly/CustomFieldDefinition_Test.php
new file mode 100644
index 00000000..80a8a997
--- /dev/null
+++ b/Tests/Recurly/CustomFieldDefinition_Test.php
@@ -0,0 +1,23 @@
+client->addResponse(
+ 'GET',
+ '/custom_field_definitions/3722298505492673710',
+ 'custom_field_definitions/show-200.xml'
+ );
+
+ $custom_field_definition = Recurly_CustomFieldDefinition::get('3722298505492673710', $this->client);
+ $this->assertInstanceOf('Recurly_CustomFieldDefinition', $custom_field_definition);
+ $this->assertEquals($custom_field_definition->id, '3722298505492673710');
+ $this->assertEquals($custom_field_definition->related_type, 'plan');
+ $this->assertEquals($custom_field_definition->name, 'package');
+ $this->assertEquals($custom_field_definition->user_access, 'writable');
+ $this->assertEquals($custom_field_definition->display_name, 'Package');
+ $this->assertEquals($custom_field_definition->tooltip, 'Value can be \'Basic\' or \'Premium\'');
+ $this->assertEquals($custom_field_definition->created_at, new DateTime('2023-01-23T19:02:40Z'));
+ $this->assertEquals($custom_field_definition->updated_at, new DateTime('2023-01-23T19:02:47Z'));
+ }
+}
diff --git a/Tests/fixtures/custom_field_definitions/list-200.xml b/Tests/fixtures/custom_field_definitions/list-200.xml
new file mode 100644
index 00000000..dca96ec3
--- /dev/null
+++ b/Tests/fixtures/custom_field_definitions/list-200.xml
@@ -0,0 +1,39 @@
+HTTP/1.1 200 OK
+Content-Type: application/xml; charset=utf-8
+
+
+
+
+ 3722298505492673710
+ plan
+ package
+ writable
+ Package
+ Value can be 'Basic' or 'Premium'
+ 2023-01-23T19:02:40Z
+ 2023-01-23T19:02:47Z
+
+
+
+ 3717783227799104920
+ charge
+ size
+ api_only
+
+
+ 2023-01-17T13:31:37Z
+ 2023-01-17T13:31:37Z
+
+
+
+ 3704733972259271618
+ charge
+ color
+ api_only
+
+
+ 2022-12-30T13:25:04Z
+ 2022-12-30T13:25:04Z
+
+
+
diff --git a/Tests/fixtures/custom_field_definitions/list_filtered-200.xml b/Tests/fixtures/custom_field_definitions/list_filtered-200.xml
new file mode 100644
index 00000000..9366a26a
--- /dev/null
+++ b/Tests/fixtures/custom_field_definitions/list_filtered-200.xml
@@ -0,0 +1,28 @@
+HTTP/1.1 200 OK
+Content-Type: application/xml; charset=utf-8
+
+
+
+
+ 3717783227799104920
+ charge
+ size
+ api_only
+
+
+ 2023-01-17T13:31:37Z
+ 2023-01-17T13:31:37Z
+
+
+
+ 3704733972259271618
+ charge
+ size
+ api_only
+
+
+ 2022-12-30T13:25:04Z
+ 2022-12-30T13:25:04Z
+
+
+
diff --git a/Tests/fixtures/custom_field_definitions/show-200.xml b/Tests/fixtures/custom_field_definitions/show-200.xml
new file mode 100644
index 00000000..b1b97fda
--- /dev/null
+++ b/Tests/fixtures/custom_field_definitions/show-200.xml
@@ -0,0 +1,15 @@
+HTTP/1.1 200 OK
+Content-Type: application/xml; charset=utf-8
+
+
+
+ 3722298505492673710
+ plan
+ package
+ writable
+ Package
+ Value can be 'Basic' or 'Premium'
+ 2023-01-23T19:02:40Z
+ 2023-01-23T19:02:47Z
+
+
diff --git a/lib/recurly.php b/lib/recurly.php
index ca9807d4..fac9d384 100644
--- a/lib/recurly.php
+++ b/lib/recurly.php
@@ -34,6 +34,8 @@
require_once(__DIR__ . '/recurly/currency_percentage_tier.php');
require_once(__DIR__ . '/recurly/custom_field.php');
require_once(__DIR__ . '/recurly/custom_field_list.php');
+require_once(__DIR__ . '/recurly/custom_field_definition.php');
+require_once(__DIR__ . '/recurly/custom_field_definition_list.php');
require_once(__DIR__ . '/recurly/customer_permission.php');
require_once(__DIR__ . '/recurly/dunning_campaign.php');
require_once(__DIR__ . '/recurly/dunning_campaign_list.php');
diff --git a/lib/recurly/client.php b/lib/recurly/client.php
index 5f8beaa0..9193652d 100644
--- a/lib/recurly/client.php
+++ b/lib/recurly/client.php
@@ -71,6 +71,7 @@ class Recurly_Client
const PATH_COUPON_REDEMPTIONS = 'redemptions';
const PATH_COUPONS = 'coupons';
const PATH_CREDIT_PAYMENTS = 'credit_payments';
+ const PATH_CUSTOM_FIELD_DEFINITIONS = 'custom_field_definitions';
const PATH_GIFT_CARDS = 'gift_cards';
const PATH_UNIQUE_COUPONS = 'unique_coupon_codes';
const PATH_INVOICES = 'invoices';
diff --git a/lib/recurly/custom_field_definition.php b/lib/recurly/custom_field_definition.php
new file mode 100644
index 00000000..170836fd
--- /dev/null
+++ b/lib/recurly/custom_field_definition.php
@@ -0,0 +1,51 @@
+_href))
+ return $this->getHref();
+ else
+ return Recurly_CustomFieldDefinition::uriForCustomFieldDefinition($this->id);
+ }
+
+ protected static function uriForCustomFieldDefinition($customFieldDefinitionId) {
+ return self::_safeUri(Recurly_Client::PATH_CUSTOM_FIELD_DEFINITIONS, $customFieldDefinitionId);
+ }
+
+ protected function getNodeName() {
+ return 'custom_field_definition';
+ }
+
+ protected function getWriteableAttributes() {
+ return array(
+ 'id',
+ 'related_type',
+ 'name',
+ 'user_access',
+ 'display_name',
+ 'tooltip',
+ 'created_at',
+ 'updated_at',
+ );
+ }
+}
diff --git a/lib/recurly/custom_field_definition_list.php b/lib/recurly/custom_field_definition_list.php
new file mode 100644
index 00000000..d5993dcb
--- /dev/null
+++ b/lib/recurly/custom_field_definition_list.php
@@ -0,0 +1,18 @@
+ 'Recurly_Currency',
'custom_fields' => 'Recurly_CustomFieldList',
'custom_field' => 'Recurly_CustomField',
+ 'custom_field_definition' => 'Recurly_CustomFieldDefinition',
+ 'custom_field_definitions' => 'Recurly_CustomFieldDefinitionList',
'customer_permission' => 'Recurly_CustomerPermission',
'credit_invoices' => 'array',
'credit_payment' => 'Recurly_CreditPayment',